1use plotlars::{
2 Axis, BarPlot, BoxPlot, Dimensions, Legend, Line, Orientation, Plot, Rgb, ScatterPlot, Shape,
3 SubplotGrid, Text, TickDirection, TimeSeriesPlot,
4};
5use polars::prelude::*;
6
7fn main() {
8 let penguins_dataset = LazyCsvReader::new(PlPath::new("data/penguins.csv"))
9 .finish()
10 .unwrap()
11 .select([
12 col("species"),
13 col("sex").alias("gender"),
14 col("flipper_length_mm").cast(DataType::Int16),
15 col("body_mass_g").cast(DataType::Int16),
16 ])
17 .collect()
18 .unwrap();
19
20 let temperature_dataset = LazyCsvReader::new(PlPath::new("data/debilt_2023_temps.csv"))
21 .with_has_header(true)
22 .with_try_parse_dates(true)
23 .finish()
24 .unwrap()
25 .with_columns(vec![
26 (col("tavg") / lit(10)).alias("tavg"),
27 (col("tmin") / lit(10)).alias("tmin"),
28 (col("tmax") / lit(10)).alias("tmax"),
29 ])
30 .collect()
31 .unwrap();
32
33 let animals_dataset = LazyCsvReader::new(PlPath::new("data/animal_statistics.csv"))
34 .finish()
35 .unwrap()
36 .collect()
37 .unwrap();
38
39 let axis = Axis::new()
40 .show_line(true)
41 .tick_direction(TickDirection::OutSide)
42 .value_thousands(true);
43
44 let plot1 = TimeSeriesPlot::builder()
45 .data(&temperature_dataset)
46 .x("date")
47 .y("tavg")
48 .additional_series(vec!["tmin", "tmax"])
49 .colors(vec![Rgb(128, 128, 128), Rgb(0, 122, 255), Rgb(255, 128, 0)])
50 .lines(vec![Line::Solid, Line::Dot, Line::Dot])
51 .plot_title(
52 Text::from("De Bilt Temperature 2023")
53 .font("Arial Bold")
54 .size(16),
55 )
56 .y_title(Text::from("temperature (°C)").size(13).x(-0.08))
57 .legend(&Legend::new().x(0.1).y(0.9))
59 .build();
60
61 let plot2 = ScatterPlot::builder()
62 .data(&penguins_dataset)
63 .x("body_mass_g")
64 .y("flipper_length_mm")
65 .group("species")
66 .sort_groups_by(|a, b| {
67 if a.len() == b.len() {
68 a.cmp(b)
69 } else {
70 a.len().cmp(&b.len())
71 }
72 })
73 .opacity(0.6)
74 .size(10)
75 .colors(vec![Rgb(178, 34, 34), Rgb(65, 105, 225), Rgb(255, 140, 0)])
76 .shapes(vec![Shape::Circle, Shape::Square, Shape::Diamond])
77 .plot_title(Text::from("Penguin Morphology").font("Arial Bold").size(16))
78 .x_title(Text::from("body mass (g)").size(13))
79 .y_title(Text::from("flipper length (mm)").size(13).x(-0.11))
80 .legend_title(Text::from("Species").size(12))
81 .x_axis(&axis.clone().value_range(vec![2500.0, 6500.0]))
82 .y_axis(&axis.clone().value_range(vec![170.0, 240.0]))
83 .legend(&Legend::new().x(0.85).y(0.4))
84 .build();
85
86 let plot3 = BarPlot::builder()
87 .data(&animals_dataset)
88 .labels("animal")
89 .values("value")
90 .orientation(Orientation::Vertical)
91 .group("gender")
92 .sort_groups_by(|a, b| a.len().cmp(&b.len()))
93 .error("error")
94 .colors(vec![Rgb(255, 127, 80), Rgb(64, 224, 208)])
95 .plot_title(Text::from("Animal Statistics").font("Arial Bold").size(16))
96 .x_title(Text::from("animal").size(13))
97 .y_title(Text::from("value").size(13))
98 .legend_title(Text::from("Gender").size(12))
99 .legend(
100 &Legend::new()
101 .orientation(Orientation::Horizontal)
102 .x(0.35)
103 .y(0.9),
104 )
105 .build();
106
107 let plot4 = BoxPlot::builder()
108 .data(&penguins_dataset)
109 .labels("species")
110 .values("body_mass_g")
111 .orientation(Orientation::Vertical)
112 .group("gender")
113 .box_points(true)
114 .point_offset(-1.5)
115 .jitter(0.01)
116 .opacity(0.15)
117 .colors(vec![Rgb(0, 191, 255), Rgb(57, 255, 20), Rgb(255, 105, 180)])
118 .plot_title(
119 Text::from("Body Mass Distribution")
120 .font("Arial Bold")
121 .size(16),
122 )
123 .x_title(Text::from("species").size(13))
124 .y_title(Text::from("body mass (g)").size(13).x(-0.12))
125 .legend_title(Text::from("Gender").size(12))
126 .y_axis(&Axis::new().value_thousands(true))
127 .legend(&Legend::new().x(0.85).y(0.9))
128 .build();
129
130 let dimensions = Dimensions::new().width(1400).height(850).auto_size(false);
131
132 SubplotGrid::regular()
133 .plots(vec![&plot1, &plot2, &plot3, &plot4])
134 .rows(2)
135 .cols(2)
136 .v_gap(0.3)
137 .h_gap(0.2)
138 .dimensions(&dimensions)
139 .title(
140 Text::from("Scientific Data Visualization Dashboard")
141 .size(26)
142 .font("Arial Bold"),
143 )
144 .build()
145 .plot();
146}