| 1 | use plotters::prelude::*; |
| 2 | |
| 3 | use chrono::{TimeZone, Utc}; |
| 4 | |
| 5 | use std::error::Error; |
| 6 | |
| 7 | const OUT_FILE_NAME: &'static str = "plotters-doc-data/slc-temp.png" ; |
| 8 | fn main() -> Result<(), Box<dyn Error>> { |
| 9 | let root = BitMapBackend::new(OUT_FILE_NAME, (1024, 768)).into_drawing_area(); |
| 10 | |
| 11 | root.fill(&WHITE)?; |
| 12 | |
| 13 | let mut chart = ChartBuilder::on(&root) |
| 14 | .margin(10) |
| 15 | .caption( |
| 16 | "Monthly Average Temperate in Salt Lake City, UT" , |
| 17 | ("sans-serif" , 40), |
| 18 | ) |
| 19 | .set_label_area_size(LabelAreaPosition::Left, 60) |
| 20 | .set_label_area_size(LabelAreaPosition::Right, 60) |
| 21 | .set_label_area_size(LabelAreaPosition::Bottom, 40) |
| 22 | .build_cartesian_2d( |
| 23 | (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(), |
| 24 | 14.0..104.0, |
| 25 | )? |
| 26 | .set_secondary_coord( |
| 27 | (Utc.ymd(2010, 1, 1)..Utc.ymd(2018, 12, 1)).monthly(), |
| 28 | -10.0..40.0, |
| 29 | ); |
| 30 | |
| 31 | chart |
| 32 | .configure_mesh() |
| 33 | .disable_x_mesh() |
| 34 | .disable_y_mesh() |
| 35 | .x_labels(30) |
| 36 | .max_light_lines(4) |
| 37 | .y_desc("Average Temp (F)" ) |
| 38 | .draw()?; |
| 39 | chart |
| 40 | .configure_secondary_axes() |
| 41 | .y_desc("Average Temp (C)" ) |
| 42 | .draw()?; |
| 43 | |
| 44 | chart.draw_series(LineSeries::new( |
| 45 | DATA.iter().map(|(y, m, t)| (Utc.ymd(*y, *m, 1), *t)), |
| 46 | &BLUE, |
| 47 | ))?; |
| 48 | |
| 49 | chart.draw_series( |
| 50 | DATA.iter() |
| 51 | .map(|(y, m, t)| Circle::new((Utc.ymd(*y, *m, 1), *t), 3, BLUE.filled())), |
| 52 | )?; |
| 53 | |
| 54 | // To avoid the IO failure being ignored silently, we manually call the present function |
| 55 | root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir" ); |
| 56 | println!("Result has been saved to {}" , OUT_FILE_NAME); |
| 57 | |
| 58 | Ok(()) |
| 59 | } |
| 60 | |
| 61 | const DATA: [(i32, u32, f64); 12 * 9] = [ |
| 62 | (2010, 1, 32.4), |
| 63 | (2010, 2, 37.5), |
| 64 | (2010, 3, 44.5), |
| 65 | (2010, 4, 50.3), |
| 66 | (2010, 5, 55.0), |
| 67 | (2010, 6, 70.0), |
| 68 | (2010, 7, 78.7), |
| 69 | (2010, 8, 76.5), |
| 70 | (2010, 9, 68.9), |
| 71 | (2010, 10, 56.3), |
| 72 | (2010, 11, 40.3), |
| 73 | (2010, 12, 36.5), |
| 74 | (2011, 1, 28.8), |
| 75 | (2011, 2, 35.1), |
| 76 | (2011, 3, 45.5), |
| 77 | (2011, 4, 48.9), |
| 78 | (2011, 5, 55.1), |
| 79 | (2011, 6, 68.8), |
| 80 | (2011, 7, 77.9), |
| 81 | (2011, 8, 78.4), |
| 82 | (2011, 9, 68.2), |
| 83 | (2011, 10, 55.0), |
| 84 | (2011, 11, 41.5), |
| 85 | (2011, 12, 31.0), |
| 86 | (2012, 1, 35.6), |
| 87 | (2012, 2, 38.1), |
| 88 | (2012, 3, 49.1), |
| 89 | (2012, 4, 56.1), |
| 90 | (2012, 5, 63.4), |
| 91 | (2012, 6, 73.0), |
| 92 | (2012, 7, 79.0), |
| 93 | (2012, 8, 79.0), |
| 94 | (2012, 9, 68.8), |
| 95 | (2012, 10, 54.9), |
| 96 | (2012, 11, 45.2), |
| 97 | (2012, 12, 34.9), |
| 98 | (2013, 1, 19.7), |
| 99 | (2013, 2, 31.1), |
| 100 | (2013, 3, 46.2), |
| 101 | (2013, 4, 49.8), |
| 102 | (2013, 5, 61.3), |
| 103 | (2013, 6, 73.3), |
| 104 | (2013, 7, 80.3), |
| 105 | (2013, 8, 77.2), |
| 106 | (2013, 9, 68.3), |
| 107 | (2013, 10, 52.0), |
| 108 | (2013, 11, 43.2), |
| 109 | (2013, 12, 25.7), |
| 110 | (2014, 1, 31.5), |
| 111 | (2014, 2, 39.3), |
| 112 | (2014, 3, 46.4), |
| 113 | (2014, 4, 52.5), |
| 114 | (2014, 5, 63.0), |
| 115 | (2014, 6, 71.3), |
| 116 | (2014, 7, 81.0), |
| 117 | (2014, 8, 75.3), |
| 118 | (2014, 9, 70.0), |
| 119 | (2014, 10, 58.6), |
| 120 | (2014, 11, 42.1), |
| 121 | (2014, 12, 38.0), |
| 122 | (2015, 1, 35.3), |
| 123 | (2015, 2, 45.2), |
| 124 | (2015, 3, 50.9), |
| 125 | (2015, 4, 54.3), |
| 126 | (2015, 5, 60.5), |
| 127 | (2015, 6, 77.1), |
| 128 | (2015, 7, 76.2), |
| 129 | (2015, 8, 77.3), |
| 130 | (2015, 9, 70.4), |
| 131 | (2015, 10, 60.6), |
| 132 | (2015, 11, 40.9), |
| 133 | (2015, 12, 32.4), |
| 134 | (2016, 1, 31.5), |
| 135 | (2016, 2, 35.1), |
| 136 | (2016, 3, 49.1), |
| 137 | (2016, 4, 55.1), |
| 138 | (2016, 5, 60.9), |
| 139 | (2016, 6, 76.9), |
| 140 | (2016, 7, 80.0), |
| 141 | (2016, 8, 77.0), |
| 142 | (2016, 9, 67.1), |
| 143 | (2016, 10, 59.1), |
| 144 | (2016, 11, 47.4), |
| 145 | (2016, 12, 31.8), |
| 146 | (2017, 1, 29.4), |
| 147 | (2017, 2, 42.4), |
| 148 | (2017, 3, 51.7), |
| 149 | (2017, 4, 51.7), |
| 150 | (2017, 5, 62.5), |
| 151 | (2017, 6, 74.8), |
| 152 | (2017, 7, 81.3), |
| 153 | (2017, 8, 78.1), |
| 154 | (2017, 9, 65.7), |
| 155 | (2017, 10, 52.5), |
| 156 | (2017, 11, 49.0), |
| 157 | (2017, 12, 34.4), |
| 158 | (2018, 1, 38.1), |
| 159 | (2018, 2, 37.5), |
| 160 | (2018, 3, 45.4), |
| 161 | (2018, 4, 54.6), |
| 162 | (2018, 5, 64.0), |
| 163 | (2018, 6, 74.9), |
| 164 | (2018, 7, 82.5), |
| 165 | (2018, 8, 78.1), |
| 166 | (2018, 9, 71.9), |
| 167 | (2018, 10, 53.2), |
| 168 | (2018, 11, 39.7), |
| 169 | (2018, 12, 33.6), |
| 170 | ]; |
| 171 | #[test] |
| 172 | fn entry_point() { |
| 173 | main().unwrap() |
| 174 | } |
| 175 | |