Skip to content

Commit 3903ddd

Browse files
use association functions
1 parent 521832b commit 3903ddd

File tree

2 files changed

+86
-86
lines changed

2 files changed

+86
-86
lines changed

Diff for: src/boxplot.rs

+84-84
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ use std::fmt::Write;
8585
/// ## Grouped boxplot (Data as a nested list for each group)
8686
///
8787
/// ```
88-
/// use plotpy::{Boxplot, adjust_positions_and_width, Plot, StrError};
88+
/// use plotpy::{Boxplot, Plot, StrError};
8989
///
9090
/// fn main() -> Result<(), StrError> {
9191
/// let data1 = vec![
@@ -103,7 +103,7 @@ use std::fmt::Write;
103103
/// let datasets = vec![&data1, &data2];
104104
///
105105
/// // Adjust the positions and width for each group
106-
/// let (positions, width) = adjust_positions_and_width(&datasets, 0.1, 0.6);
106+
/// let (positions, width) = Boxplot::adjust_positions_and_width(&datasets, 0.1, 0.6);
107107
///
108108
/// // x ticks and labels
109109
/// let ticks: Vec<_> = (1..(datasets[0].len() + 1)).into_iter().collect();
@@ -342,6 +342,85 @@ impl Boxplot {
342342
}
343343
opt
344344
}
345+
346+
/// A helper function to adjust the boxes positions and width to beautify the layout when plotting grouped boxplot
347+
///
348+
/// # Input
349+
///
350+
/// * `datasets` is a sequence of data ( a sequence of 1D arrays) used by `draw`.
351+
/// * `gap`: Shrink on the orient axis by this factor to add a gap between dodged elements. 0.0-0.5 usually gives a beautiful layout.
352+
/// * `span`: The total width of boxes and gaps in a position. 0.5-1.0 usually gives a beautiful layout.
353+
///
354+
/// # Notes
355+
///
356+
/// * The type `T` must be a number.
357+
pub fn adjust_positions_and_width<T>(datasets: &Vec<&Vec<Vec<T>>>, gap: f64, span: f64) -> (Vec<Vec<f64>>, f64)
358+
where
359+
T: std::fmt::Display,
360+
{
361+
let groups = datasets.len(); // The number of groups
362+
let gap = gap;
363+
let span = span;
364+
365+
// Generate the adjusted width of a box
366+
let mut width: f64 = 0.5;
367+
width = width.min(span/(groups as f64 + (groups-1) as f64*gap));
368+
369+
// Generate the position offset for each box by an empirical formula. seaborn and plotnine all have their own algorithms.
370+
let offsets: Vec<f64> = ((1 - groups as i64)..=(groups as i64 - 1)).step_by(2).map(|x| x as f64 * width * (1.0+gap)/2.0).collect();
371+
372+
let mut positions = Vec::new();
373+
for i in 0..groups {
374+
let mut position = Vec::new();
375+
for j in 0..datasets[i].len() {
376+
position.push((j+1) as f64 + offsets[i]);
377+
}
378+
positions.push(position);
379+
}
380+
381+
// Return the adjusted positions and width for each group
382+
(positions, width)
383+
}
384+
385+
/// A helper function to adjust the boxes positions and width to beautify the layout for `draw_mat` when plotting grouped boxplot
386+
///
387+
/// # Input
388+
///
389+
/// * `datasets`: A sequence of data (2D array) used by `draw_mat`.
390+
/// * `gap`: Shrink on the orient axis by this factor to add a gap between dodged elements. 0.0-0.5 usually gives a beautiful layout.
391+
/// * `span`: The total width of boxes and gaps in a position. 0.0-1.0 usually gives a beautiful layout.
392+
///
393+
/// # Notes
394+
///
395+
/// * The type `U` must be a number.
396+
pub fn adjust_positions_and_width_mat<'a, T, U>(datasets: &Vec<&'a T>, gap: f64, span: f64) -> (Vec<Vec<f64>>, f64)
397+
where
398+
T: AsMatrix<'a, U>,
399+
U: 'a + std::fmt::Display,
400+
{
401+
let groups = datasets.len(); // The number of groups
402+
let gap = gap;
403+
let span = span;
404+
405+
// Generate the adjusted width of a box
406+
let mut width: f64 = 0.5;
407+
width = width.min(span/(groups as f64 + (groups-1) as f64*gap));
408+
409+
// Generate the position offset for each box by an empirical formula. seaborn and plotnine all have their own algorithms.
410+
let offsets: Vec<f64> = ((1 - groups as i64)..=(groups as i64 - 1)).step_by(2).map(|x| x as f64 * width * (1.0+gap)/2.0).collect();
411+
412+
let mut positions = Vec::new();
413+
for i in 0..groups {
414+
let mut position = Vec::new();
415+
for j in 0..datasets[i].size().1 {
416+
position.push((j+1) as f64 + offsets[i]);
417+
}
418+
positions.push(position);
419+
}
420+
421+
// Return the adjusted positions and width for each group
422+
(positions, width)
423+
}
345424
}
346425

347426
impl GraphMaker for Boxplot {
@@ -353,90 +432,11 @@ impl GraphMaker for Boxplot {
353432
}
354433
}
355434

356-
/// A helper function to adjust the boxes positions and width to beautify the layout when plotting grouped boxplot
357-
///
358-
/// # Input
359-
///
360-
/// * `datasets` is a sequence of data ( a sequence of 1D arrays) used by `draw`.
361-
/// * `gap`: Shrink on the orient axis by this factor to add a gap between dodged elements. 0.0-0.5 usually gives a beautiful layout.
362-
/// * `span`: The total width of boxes and gaps in a position. 0.5-1.0 usually gives a beautiful layout.
363-
///
364-
/// # Notes
365-
///
366-
/// * The type `T` must be a number.
367-
pub fn adjust_positions_and_width<T>(datasets: &Vec<&Vec<Vec<T>>>, gap: f64, span: f64) -> (Vec<Vec<f64>>, f64)
368-
where
369-
T: std::fmt::Display,
370-
{
371-
let groups = datasets.len(); // The number of groups
372-
let gap = gap;
373-
let span = span;
374-
375-
// Generate the adjusted width of a box
376-
let mut width: f64 = 0.5;
377-
width = width.min(span/(groups as f64 + (groups-1) as f64*gap));
378-
379-
// Generate the position offset for each box by an empirical formula. seaborn and plotnine all have their own algorithms.
380-
let offsets: Vec<f64> = ((1 - groups as i64)..=(groups as i64 - 1)).step_by(2).map(|x| x as f64 * width * (1.0+gap)/2.0).collect();
381-
382-
let mut positions = Vec::new();
383-
for i in 0..groups {
384-
let mut position = Vec::new();
385-
for j in 0..datasets[i].len() {
386-
position.push((j+1) as f64 + offsets[i]);
387-
}
388-
positions.push(position);
389-
}
390-
391-
// Return the adjusted positions and width for each group
392-
(positions, width)
393-
}
394-
395-
/// A helper function to adjust the boxes positions and width to beautify the layout for `draw_mat` when plotting grouped boxplot
396-
///
397-
/// # Input
398-
///
399-
/// * `datasets`: A sequence of data (2D array) used by `draw_mat`.
400-
/// * `gap`: Shrink on the orient axis by this factor to add a gap between dodged elements. 0.0-0.5 usually gives a beautiful layout.
401-
/// * `span`: The total width of boxes and gaps in a position. 0.0-1.0 usually gives a beautiful layout.
402-
///
403-
/// # Notes
404-
///
405-
/// * The type `U` must be a number.
406-
pub fn adjust_positions_and_width_mat<'a, T, U>(datasets: &Vec<&'a T>, gap: f64, span: f64) -> (Vec<Vec<f64>>, f64)
407-
where
408-
T: AsMatrix<'a, U>,
409-
U: 'a + std::fmt::Display,
410-
{
411-
let groups = datasets.len(); // The number of groups
412-
let gap = gap;
413-
let span = span;
414-
415-
// Generate the adjusted width of a box
416-
let mut width: f64 = 0.5;
417-
width = width.min(span/(groups as f64 + (groups-1) as f64*gap));
418-
419-
// Generate the position offset for each box by an empirical formula. seaborn and plotnine all have their own algorithms.
420-
let offsets: Vec<f64> = ((1 - groups as i64)..=(groups as i64 - 1)).step_by(2).map(|x| x as f64 * width * (1.0+gap)/2.0).collect();
421-
422-
let mut positions = Vec::new();
423-
for i in 0..groups {
424-
let mut position = Vec::new();
425-
for j in 0..datasets[i].size().1 {
426-
position.push((j+1) as f64 + offsets[i]);
427-
}
428-
positions.push(position);
429-
}
430-
431-
// Return the adjusted positions and width for each group
432-
(positions, width)
433-
}
434-
435435
/////////////////////////////////////////////////////////////////////////////
436436

437437
#[cfg(test)]
438438
mod tests {
439-
use super::{Boxplot, adjust_positions_and_width, adjust_positions_and_width_mat};
439+
use super::Boxplot;
440440
use crate::GraphMaker;
441441

442442
#[test]
@@ -561,7 +561,7 @@ mod tests {
561561
vec![5, 6, 7, 8, 9],
562562
vec![6, 7, 8, 9, 10],];
563563
let datasets = vec![&data1, &data2];
564-
let (positions, width) = adjust_positions_and_width(&datasets, 0.1, 0.6);
564+
let (positions, width) = Boxplot::adjust_positions_and_width(&datasets, 0.1, 0.6);
565565
assert_eq!(positions, vec![vec![0.8428571428571429, 1.842857142857143, 2.842857142857143, 3.842857142857143, 4.8428571428571425],
566566
vec![1.157142857142857, 2.157142857142857, 3.157142857142857, 4.1571428571428575, 5.1571428571428575]]);
567567
assert_eq!(width, 0.2857142857142857);
@@ -582,7 +582,7 @@ mod tests {
582582
vec![5, 6, 7, 8, 9],
583583
vec![6, 7, 8, 9, 10],];
584584
let datasets = vec![&data1, &data2];
585-
let (positions, width) = adjust_positions_and_width_mat(&datasets, 0.1, 0.6);
585+
let (positions, width) = Boxplot::adjust_positions_and_width_mat(&datasets, 0.1, 0.6);
586586
assert_eq!(positions, vec![vec![0.8428571428571429, 1.842857142857143, 2.842857142857143, 3.842857142857143, 4.8428571428571425],
587587
vec![1.157142857142857, 2.157142857142857, 3.157142857142857, 4.1571428571428575, 5.1571428571428575]]);
588588
assert_eq!(width, 0.2857142857142857);

Diff for: tests/test_boxplot.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use plotpy::{Boxplot, adjust_positions_and_width, Plot, StrError};
1+
use plotpy::{Boxplot, Plot, StrError};
22
use std::fs::File;
33
use std::io::{BufRead, BufReader};
44
use std::path::Path;
@@ -233,7 +233,7 @@ fn test_boxplot_6() -> Result<(), StrError> {
233233
let datasets = vec![&data1, &data2];
234234

235235
// Adjust the positions and width for each group
236-
let (positions, width) = adjust_positions_and_width(&datasets, 0.1, 0.6);
236+
let (positions, width) = Boxplot::adjust_positions_and_width(&datasets, 0.1, 0.6);
237237

238238
// x ticks and labels
239239
let ticks: Vec<_> = (1..(datasets[0].len() + 1)).into_iter().collect();

0 commit comments

Comments
 (0)