use super::{generate_list, generate_nested_list, matrix_to_array, AsMatrix, GraphMaker};
use num_traits::Num;
use std::fmt::Write;
pub struct Boxplot {
symbol: String, horizontal: bool, whisker: Option<f64>, positions: Vec<f64>, width: Option<f64>, no_fliers: bool, patch_artist: bool, median_props: String, box_props: String, whisker_props: String, extra: String, buffer: String, }
impl Boxplot {
pub fn new() -> Self {
Boxplot {
symbol: String::new(),
horizontal: false,
whisker: None,
positions: Vec::new(),
width: None,
no_fliers: false,
patch_artist: false,
median_props: String::new(),
box_props: String::new(),
whisker_props: String::new(),
extra: String::new(),
buffer: String::new(),
}
}
pub fn draw<T>(&mut self, data: &Vec<Vec<T>>)
where
T: std::fmt::Display + Num,
{
generate_nested_list(&mut self.buffer, "x", data);
if self.positions.len() > 0 {
generate_list(&mut self.buffer, "positions", self.positions.as_slice());
}
let opt = self.options();
write!(&mut self.buffer, "p=plt.boxplot(x{})\n", &opt).unwrap();
}
pub fn draw_mat<'a, T, U>(&mut self, data: &'a T)
where
T: AsMatrix<'a, U>,
U: 'a + std::fmt::Display + Num,
{
matrix_to_array(&mut self.buffer, "x", data);
if self.positions.len() > 0 {
generate_list(&mut self.buffer, "positions", self.positions.as_slice());
}
let opt = self.options();
write!(&mut self.buffer, "p=plt.boxplot(x{})\n", &opt).unwrap();
}
pub fn set_symbol(&mut self, symbol: &str) -> &mut Self {
self.symbol = symbol.to_string();
self
}
pub fn set_horizontal(&mut self, flag: bool) -> &mut Self {
self.horizontal = flag;
self
}
pub fn set_whisker(&mut self, whisker: f64) -> &mut Self {
self.whisker = Some(whisker);
self
}
pub fn set_positions(&mut self, positions: &[f64]) -> &mut Self {
self.positions = positions.to_vec();
self
}
pub fn set_width(&mut self, width: f64) -> &mut Self {
self.width = Some(width);
self
}
pub fn set_no_fliers(&mut self, flag: bool) -> &mut Self {
self.no_fliers = flag;
self
}
pub fn set_patch_artist(&mut self, flag: bool) -> &mut Self {
self.patch_artist = flag;
self
}
pub fn set_medianprops(&mut self, props: &str) -> &mut Self {
self.median_props = props.to_string();
self
}
pub fn set_boxprops(&mut self, props: &str) -> &mut Self {
self.box_props = props.to_string();
self
}
pub fn set_whiskerprops(&mut self, props: &str) -> &mut Self {
self.whisker_props = props.to_string();
self
}
pub fn set_extra(&mut self, extra: &str) -> &mut Self {
self.extra = extra.to_string();
self
}
fn options(&self) -> String {
let mut opt = String::new();
if self.symbol != "" {
write!(&mut opt, ",sym=r'{}'", self.symbol).unwrap();
}
if self.horizontal {
write!(&mut opt, ",vert=False").unwrap();
}
if self.whisker != None {
write!(&mut opt, ",whis={}", self.whisker.unwrap()).unwrap();
}
if self.positions.len() > 0 {
write!(&mut opt, ",positions=positions").unwrap();
}
if self.width != None {
write!(&mut opt, ",widths={}", self.width.unwrap()).unwrap();
}
if self.no_fliers {
write!(&mut opt, ",showfliers=False").unwrap();
}
if self.patch_artist {
write!(&mut opt, ",patch_artist=True").unwrap();
}
if self.median_props != "" {
write!(&mut opt, ",medianprops={}", self.median_props).unwrap();
}
if self.box_props != "" {
write!(&mut opt, ",boxprops={}", self.box_props).unwrap();
}
if self.whisker_props != "" {
write!(&mut opt, ",whiskerprops={}", self.whisker_props).unwrap();
}
if self.extra != "" {
write!(&mut opt, ",{}", self.extra).unwrap();
}
opt
}
}
impl GraphMaker for Boxplot {
fn get_buffer<'a>(&'a self) -> &'a String {
&self.buffer
}
fn clear_buffer(&mut self) {
self.buffer.clear();
}
}
#[cfg(test)]
mod tests {
use super::Boxplot;
use crate::GraphMaker;
#[test]
fn new_works() {
let boxes = Boxplot::new();
assert_eq!(boxes.symbol.len(), 0);
assert_eq!(boxes.horizontal, false);
assert_eq!(boxes.whisker, None);
assert_eq!(boxes.positions.len(), 0);
assert_eq!(boxes.width, None);
assert_eq!(boxes.no_fliers, false);
assert_eq!(boxes.patch_artist, false);
assert_eq!(boxes.median_props.len(), 0);
assert_eq!(boxes.box_props.len(), 0);
assert_eq!(boxes.whisker_props.len(), 0);
assert_eq!(boxes.extra.len(), 0);
assert_eq!(boxes.buffer.len(), 0);
}
#[test]
fn draw_works_1() {
let x = vec![
vec![1, 2, 3], vec![2, 3, 4, 5, 6], vec![6, 7], ];
let mut boxes = Boxplot::new();
boxes.draw(&x);
let b: &str = "x=[[1,2,3,],[2,3,4,5,6,],[6,7,],]\n\
p=plt.boxplot(x)\n";
assert_eq!(boxes.buffer, b);
boxes.clear_buffer();
assert_eq!(boxes.buffer, "");
}
#[test]
fn draw_works_2() {
let x = vec![
vec![1, 2, 3], vec![2, 3, 4, 5, 6], vec![6, 7], ];
let mut boxes = Boxplot::new();
boxes
.set_symbol("b+")
.set_no_fliers(true)
.set_horizontal(true)
.set_whisker(1.5)
.set_positions(&[1.0, 2.0, 3.0])
.set_width(0.5)
.set_patch_artist(true)
.set_boxprops("{'facecolor': 'C0', 'edgecolor': 'white','linewidth': 0.5}")
.draw(&x);
let b: &str = "x=[[1,2,3,],[2,3,4,5,6,],[6,7,],]\n\
positions=[1,2,3,]\n\
p=plt.boxplot(x,sym=r'b+',vert=False,whis=1.5,positions=positions,widths=0.5,showfliers=False,patch_artist=True,boxprops={'facecolor': 'C0', 'edgecolor': 'white','linewidth': 0.5})\n";
assert_eq!(boxes.buffer, b);
boxes.clear_buffer();
assert_eq!(boxes.buffer, "");
}
#[test]
fn draw_mat_works_1() {
let x = vec![
vec![1, 2, 3, 4, 5],
vec![2, 3, 4, 5, 6],
vec![3, 4, 5, 6, 7],
vec![4, 5, 6, 7, 8],
vec![5, 6, 7, 8, 9],
vec![6, 7, 8, 9, 10],
];
let mut boxes = Boxplot::new();
boxes.draw_mat(&x);
let b: &str = "x=np.array([[1,2,3,4,5,],[2,3,4,5,6,],[3,4,5,6,7,],[4,5,6,7,8,],[5,6,7,8,9,],[6,7,8,9,10,],])\n\
p=plt.boxplot(x)\n";
assert_eq!(boxes.buffer, b);
boxes.clear_buffer();
assert_eq!(boxes.buffer, "");
}
#[test]
fn draw_mat_works_2() {
let x = vec![
vec![1, 2, 3, 4, 5],
vec![2, 3, 4, 5, 6],
vec![3, 4, 5, 6, 7],
vec![4, 5, 6, 7, 8],
vec![5, 6, 7, 8, 9],
vec![6, 7, 8, 9, 10],
];
let mut boxes = Boxplot::new();
boxes
.set_symbol("b+")
.set_no_fliers(true)
.set_horizontal(true)
.set_whisker(1.5)
.set_positions(&[1.0, 2.0, 3.0, 4.0, 5.0])
.set_width(0.5)
.draw_mat(&x);
let b: &str = "x=np.array([[1,2,3,4,5,],[2,3,4,5,6,],[3,4,5,6,7,],[4,5,6,7,8,],[5,6,7,8,9,],[6,7,8,9,10,],])\n\
positions=[1,2,3,4,5,]\n\
p=plt.boxplot(x,sym=r'b+',vert=False,whis=1.5,positions=positions,widths=0.5,showfliers=False)\n";
assert_eq!(boxes.buffer, b);
boxes.clear_buffer();
assert_eq!(boxes.buffer, "");
}
}