use plotters::prelude::*;
use plotters_statistical::series::gain_chart::GainMode;
use plotters_statistical::style::palette_color;
use plotters_statistical::GainChart;
fn noise(i: usize) -> f64 {
((i as f64 * 12.9898).sin() * 43758.5453).rem_euclid(1.0)
}
fn dataset() -> (Vec<f64>, Vec<bool>) {
let n = 400;
let mut scores = Vec::with_capacity(n);
let mut labels = Vec::with_capacity(n);
for i in 0..n {
let pos = i % 5 == 0; scores.push(if pos { 0.6 } else { 0.0 } + noise(i));
labels.push(pos);
}
(scores, labels)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = SVGBackend::new("gain_chart.svg", (960, 460)).into_drawing_area();
root.fill(&WHITE)?;
let (left, right) = root.split_horizontally(480);
let (scores, labels) = dataset();
let mut gchart = ChartBuilder::on(&left)
.caption("Cumulative gain", ("sans-serif", 20))
.margin(20)
.set_label_area_size(LabelAreaPosition::Left, 45)
.set_label_area_size(LabelAreaPosition::Bottom, 40)
.build_cartesian_2d(0f64..1f64, 0f64..1f64)?;
gchart
.configure_mesh()
.x_desc("fraction targeted")
.y_desc("fraction of positives")
.draw()?;
gchart.draw_series(std::iter::once(
GainChart::from_scores(&scores, &labels)?.color(palette_color(0)),
))?;
let mut lchart = ChartBuilder::on(&right)
.caption("Lift", ("sans-serif", 20))
.margin(20)
.set_label_area_size(LabelAreaPosition::Left, 45)
.set_label_area_size(LabelAreaPosition::Bottom, 40)
.build_cartesian_2d(0f64..1f64, 0f64..5f64)?;
lchart
.configure_mesh()
.x_desc("fraction targeted")
.y_desc("lift")
.draw()?;
lchart.draw_series(std::iter::once(
GainChart::from_scores(&scores, &labels)?
.mode(GainMode::Lift)
.color(palette_color(1)),
))?;
root.present()?;
println!("wrote gain_chart.svg");
Ok(())
}