@@ -85,7 +85,7 @@ use std::fmt::Write;
85
85
/// ## Grouped boxplot (Data as a nested list for each group)
86
86
///
87
87
/// ```
88
- /// use plotpy::{Boxplot, adjust_positions_and_width, Plot, StrError};
88
+ /// use plotpy::{Boxplot, Plot, StrError};
89
89
///
90
90
/// fn main() -> Result<(), StrError> {
91
91
/// let data1 = vec![
@@ -103,7 +103,7 @@ use std::fmt::Write;
103
103
/// let datasets = vec![&data1, &data2];
104
104
///
105
105
/// // 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);
107
107
///
108
108
/// // x ticks and labels
109
109
/// let ticks: Vec<_> = (1..(datasets[0].len() + 1)).into_iter().collect();
@@ -342,6 +342,85 @@ impl Boxplot {
342
342
}
343
343
opt
344
344
}
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
+ }
345
424
}
346
425
347
426
impl GraphMaker for Boxplot {
@@ -353,90 +432,11 @@ impl GraphMaker for Boxplot {
353
432
}
354
433
}
355
434
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
-
435
435
/////////////////////////////////////////////////////////////////////////////
436
436
437
437
#[ cfg( test) ]
438
438
mod tests {
439
- use super :: { Boxplot , adjust_positions_and_width , adjust_positions_and_width_mat } ;
439
+ use super :: Boxplot ;
440
440
use crate :: GraphMaker ;
441
441
442
442
#[ test]
@@ -561,7 +561,7 @@ mod tests {
561
561
vec![ 5 , 6 , 7 , 8 , 9 ] ,
562
562
vec![ 6 , 7 , 8 , 9 , 10 ] , ] ;
563
563
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 ) ;
565
565
assert_eq ! ( positions, vec![ vec![ 0.8428571428571429 , 1.842857142857143 , 2.842857142857143 , 3.842857142857143 , 4.8428571428571425 ] ,
566
566
vec![ 1.157142857142857 , 2.157142857142857 , 3.157142857142857 , 4.1571428571428575 , 5.1571428571428575 ] ] ) ;
567
567
assert_eq ! ( width, 0.2857142857142857 ) ;
@@ -582,7 +582,7 @@ mod tests {
582
582
vec![ 5 , 6 , 7 , 8 , 9 ] ,
583
583
vec![ 6 , 7 , 8 , 9 , 10 ] , ] ;
584
584
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 ) ;
586
586
assert_eq ! ( positions, vec![ vec![ 0.8428571428571429 , 1.842857142857143 , 2.842857142857143 , 3.842857142857143 , 4.8428571428571425 ] ,
587
587
vec![ 1.157142857142857 , 2.157142857142857 , 3.157142857142857 , 4.1571428571428575 , 5.1571428571428575 ] ] ) ;
588
588
assert_eq ! ( width, 0.2857142857142857 ) ;
0 commit comments