echo_state_network/
plot.rs

1#[cfg(feature = "plot")]
2pub mod plotter {
3    use plotters::prelude::*;
4
5    /// Plot the graph of the given data.
6    /// 'name' is the name of the file.
7    /// 'x' is the x-axis data.
8    /// 'ys' is the y-axis data.
9    /// 'label' is the label of the data.
10    /// 'path' is the path to save the graph.
11    pub fn plot(
12        name: &str,
13        x: Vec<f64>,
14        ys: Vec<Vec<f64>>,
15        label: Vec<String>,
16        path: Option<&str>,
17    ) -> Result<(), Box<dyn std::error::Error>> {
18        let ys = ys.iter().map(|v| v.to_vec()).collect::<Vec<_>>();
19
20        let width = 1280;
21        let height = 720;
22        let path = match path {
23            Some(p) => format!("{}/{}.png", p, name),
24            None => format!("./graph/{}.png", name),
25        };
26        let root = BitMapBackend::new(&path, (width, height)).into_drawing_area();
27
28        root.fill(&WHITE)?;
29
30        let (y_min, y_max) = ys.iter().fold((f64::NAN, f64::NAN), |(m, n), v| {
31            (
32                v.iter().fold(m, |m, n| n.min(m)),
33                v.iter().fold(n, |m, n| n.max(m)),
34            )
35        });
36
37        let font = ("sans-serif", 32);
38
39        let mut chart;
40
41        if y_min.is_sign_negative() {
42            chart = ChartBuilder::on(&root)
43                .caption(name, font.into_font())
44                .margin(10)
45                .x_label_area_size(16)
46                .y_label_area_size(42)
47                .build_cartesian_2d(
48                    (*x.first().unwrap() - 0.1)..(*x.last().unwrap() + 0.1),
49                    (y_min - 0.1)..(y_max + 0.1),
50                )?;
51        } else {
52            chart = ChartBuilder::on(&root)
53                .caption(name, font.into_font())
54                .margin(10)
55                .x_label_area_size(16)
56                .y_label_area_size(42)
57                .build_cartesian_2d(
58                    (*x.first().unwrap() - 0.1)..(*x.last().unwrap() + 0.1),
59                    0f64..(y_max + 0.1),
60                )?;
61        }
62
63        chart.configure_mesh().draw()?;
64
65        let mut line_series = vec![];
66
67        let color = [
68            RGBColor(0, 0, 255),
69            RGBColor(255, 0, 0),
70            RGBColor(0, 255, 0),
71            RGBColor(255, 255, 0),
72            RGBColor(255, 0, 255),
73            RGBColor(0, 255, 255),
74            RGBColor(128, 128, 128),
75            RGBColor(128, 0, 0),
76            RGBColor(128, 128, 0),
77            RGBColor(0, 128, 0),
78            RGBColor(128, 0, 128),
79            RGBColor(0, 128, 128),
80            RGBColor(0, 0, 128),
81            RGBColor(0, 0, 0),
82        ];
83
84        for (i, (y, l)) in ys.iter().zip(label.iter()).enumerate() {
85            let line =
86                LineSeries::new(x.iter().zip(y.iter()).map(|(x, y)| (*x, *y)), color[i % 14])
87                    .point_size(4);
88            line_series.push((line, l));
89        }
90
91        for (line, l) in line_series {
92            chart.draw_series(line)?.label(l);
93        }
94
95        Ok(())
96    }
97}