use plotters::prelude::*;
use plotters_statistical::ViolinPlotSeries;
fn sample(center: f64, spread: f64, n: usize) -> Vec<f64> {
(0..n)
.map(|i| {
let t = i as f64 / n as f64;
center + spread * ((t * std::f64::consts::TAU * 2.0).sin() + (t - 0.5) * 2.0)
})
.collect()
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = SVGBackend::new("violin_plot.svg", (960, 500)).into_drawing_area();
root.fill(&WHITE)?;
let (left, right) = root.split_horizontally(480);
let groups = || {
vec![
(1.0f64, sample(6.0, 1.5, 120)),
(2.0f64, sample(3.5, 1.0, 120)),
(3.0f64, sample(8.0, 2.0, 120)),
]
};
for (area, title, with_box) in [
(&left, "Violins", false),
(&right, "Violins + embedded box", true),
] {
let mut chart = ChartBuilder::on(area)
.caption(title, ("sans-serif", 22))
.margin(20)
.set_label_area_size(LabelAreaPosition::Left, 45)
.set_label_area_size(LabelAreaPosition::Bottom, 40)
.build_cartesian_2d(0.5f64..3.5f64, 0f64..14f64)?;
chart
.configure_mesh()
.x_desc("group")
.y_desc("value")
.draw()?;
chart.draw_series(
ViolinPlotSeries::from_samples(groups())?
.width(90)
.show_box(with_box),
)?;
}
root.present()?;
println!("wrote violin_plot.svg");
Ok(())
}