pub struct SubplotGrid { /* private fields */ }Expand description
A structure representing a subplot grid layout.
The SubplotGrid struct facilitates the creation of multi-plot layouts arranged in a grid configuration.
Plots are automatically arranged in rows and columns in row-major order (left-to-right, top-to-bottom).
Each subplot retains its own title, axis labels, and legend, providing flexibility for displaying
multiple related visualizations in a single figure.
§Features
- Automatic grid layout with configurable rows and columns
- Individual subplot titles (extracted from plot titles)
- Independent axis labels for each subplot
- Configurable horizontal and vertical spacing
- Overall figure title
- Sparse grid support (fewer plots than grid capacity)
Implementations§
Source§impl SubplotGrid
impl SubplotGrid
Sourcepub fn regular<'f1, 'f2>() -> SubplotGridRegularBuilder<'f1, 'f2>
pub fn regular<'f1, 'f2>() -> SubplotGridRegularBuilder<'f1, 'f2>
Creates a subplot grid layout.
Arranges plots in a row × column grid with automatic positioning. Plots are placed
in row-major order (left-to-right, top-to-bottom). Each subplot retains its individual title
(from the plot’s plot_title), axis labels, and legend.
§Arguments
plots- Vector of plot references to arrange in the grid. Plots are positioned in row-major order.rows- Number of rows in the grid (default: 1).cols- Number of columns in the grid (default: 1).title- Overall title for the entire subplot figure (optional).h_gap- Horizontal spacing between columns (range: 0.0 to 1.0, default: 0.1).v_gap- Vertical spacing between rows (range: 0.0 to 1.0, default: 0.1).
§Example
use plotlars::{
Axis, BarPlot, BoxPlot, Legend, Line, Orientation, Plot, Rgb, ScatterPlot, Shape,
SubplotGrid, Text, TickDirection, TimeSeriesPlot,
};
use polars::prelude::*;
let dataset1 = LazyCsvReader::new(PlRefPath::new("data/animal_statistics.csv"))
.finish()
.unwrap()
.collect()
.unwrap();
let plot1 = BarPlot::builder()
.data(&dataset1)
.labels("animal")
.values("value")
.orientation(Orientation::Vertical)
.group("gender")
.sort_groups_by(|a, b| a.len().cmp(&b.len()))
.error("error")
.colors(vec![Rgb(255, 127, 80), Rgb(64, 224, 208)])
.plot_title(Text::from("Bar Plot").x(-0.05).y(1.35).size(14))
.y_title(Text::from("value").x(-0.055).y(0.76))
.x_title(Text::from("animal").x(0.97).y(-0.2))
.legend(
&Legend::new()
.orientation(Orientation::Horizontal)
.x(0.4)
.y(1.2),
)
.build();
let dataset2 = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
.finish()
.unwrap()
.select([
col("species"),
col("sex").alias("gender"),
col("flipper_length_mm").cast(DataType::Int16),
col("body_mass_g").cast(DataType::Int16),
])
.collect()
.unwrap();
let axis = Axis::new()
.show_line(true)
.tick_direction(TickDirection::OutSide)
.value_thousands(true);
let plot2 = ScatterPlot::builder()
.data(&dataset2)
.x("body_mass_g")
.y("flipper_length_mm")
.group("species")
.sort_groups_by(|a, b| {
if a.len() == b.len() {
a.cmp(b)
} else {
a.len().cmp(&b.len())
}
})
.opacity(0.5)
.size(12)
.colors(vec![Rgb(178, 34, 34), Rgb(65, 105, 225), Rgb(255, 140, 0)])
.shapes(vec![Shape::Circle, Shape::Square, Shape::Diamond])
.plot_title(Text::from("Scatter Plot").x(-0.075).y(1.35).size(14))
.x_title(Text::from("body mass (g)").y(-0.4))
.y_title(Text::from("flipper length (mm)").x(-0.078).y(0.5))
.legend_title("species")
.x_axis(&axis.clone().value_range(vec![2500.0, 6500.0]))
.y_axis(&axis.clone().value_range(vec![170.0, 240.0]))
.legend(&Legend::new().x(0.98).y(0.95))
.build();
let dataset3 = LazyCsvReader::new(PlRefPath::new("data/debilt_2023_temps.csv"))
.with_has_header(true)
.with_try_parse_dates(true)
.finish()
.unwrap()
.with_columns(vec![
(col("tavg") / lit(10)).alias("avg"),
(col("tmin") / lit(10)).alias("min"),
(col("tmax") / lit(10)).alias("max"),
])
.collect()
.unwrap();
let plot3 = TimeSeriesPlot::builder()
.data(&dataset3)
.x("date")
.y("avg")
.additional_series(vec!["min", "max"])
.colors(vec![Rgb(128, 128, 128), Rgb(0, 122, 255), Rgb(255, 128, 0)])
.lines(vec![Line::Solid, Line::Dot, Line::Dot])
.plot_title(Text::from("Time Series Plot").x(-0.05).y(1.35).size(14))
.y_title(Text::from("temperature (ºC)").x(-0.055).y(0.6))
.legend(&Legend::new().x(0.9).y(1.25))
.build();
let plot4 = BoxPlot::builder()
.data(&dataset2)
.labels("species")
.values("body_mass_g")
.orientation(Orientation::Vertical)
.group("gender")
.box_points(true)
.point_offset(-1.5)
.jitter(0.01)
.opacity(0.1)
.colors(vec![Rgb(0, 191, 255), Rgb(57, 255, 20), Rgb(255, 105, 180)])
.plot_title(Text::from("Box Plot").x(-0.075).y(1.35).size(14))
.x_title(Text::from("species").y(-0.3))
.y_title(Text::from("body mass (g)").x(-0.08).y(0.5))
.legend_title(Text::from("gender").size(12))
.y_axis(&Axis::new().value_thousands(true))
.legend(&Legend::new().x(1.0))
.build();
SubplotGrid::regular()
.plots(vec![&plot1, &plot2, &plot3, &plot4])
.rows(2)
.cols(2)
.v_gap(0.4)
.title(
Text::from("Regular Subplot Grid")
.size(16)
.font("Arial bold")
.y(0.95),
)
.build()
.plot();
Examples found in repository?
15fn regular_grid_example() {
16 let dataset1 = LazyCsvReader::new(PlRefPath::new("data/animal_statistics.csv"))
17 .finish()
18 .unwrap()
19 .collect()
20 .unwrap();
21
22 let plot1 = BarPlot::builder()
23 .data(&dataset1)
24 .labels("animal")
25 .values("value")
26 .orientation(Orientation::Vertical)
27 .group("gender")
28 .sort_groups_by(|a, b| a.len().cmp(&b.len()))
29 .error("error")
30 .colors(vec![Rgb(255, 127, 80), Rgb(64, 224, 208)])
31 .plot_title(Text::from("Bar Plot").x(-0.05).y(1.35).size(14))
32 .y_title(Text::from("value").x(-0.055).y(0.76))
33 .x_title(Text::from("animal").x(0.97).y(-0.2))
34 .legend(
35 &Legend::new()
36 .orientation(Orientation::Horizontal)
37 .x(0.4)
38 .y(1.2),
39 )
40 .build();
41
42 let dataset2 = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
43 .finish()
44 .unwrap()
45 .select([
46 col("species"),
47 col("sex").alias("gender"),
48 col("flipper_length_mm").cast(DataType::Int16),
49 col("body_mass_g").cast(DataType::Int16),
50 ])
51 .collect()
52 .unwrap();
53
54 let axis = Axis::new()
55 .show_line(true)
56 .tick_direction(TickDirection::OutSide)
57 .value_thousands(true);
58
59 let plot2 = ScatterPlot::builder()
60 .data(&dataset2)
61 .x("body_mass_g")
62 .y("flipper_length_mm")
63 .group("species")
64 .sort_groups_by(|a, b| {
65 if a.len() == b.len() {
66 a.cmp(b)
67 } else {
68 a.len().cmp(&b.len())
69 }
70 })
71 .opacity(0.5)
72 .size(12)
73 .colors(vec![Rgb(178, 34, 34), Rgb(65, 105, 225), Rgb(255, 140, 0)])
74 .shapes(vec![Shape::Circle, Shape::Square, Shape::Diamond])
75 .plot_title(Text::from("Scatter Plot").x(-0.075).y(1.35).size(14))
76 .x_title(Text::from("body mass (g)").y(-0.4))
77 .y_title(Text::from("flipper length (mm)").x(-0.078).y(0.5))
78 .legend_title("species")
79 .x_axis(&axis.clone().value_range(vec![2500.0, 6500.0]))
80 .y_axis(&axis.clone().value_range(vec![170.0, 240.0]))
81 .legend(&Legend::new().x(0.98).y(0.95))
82 .build();
83
84 let dataset3 = LazyCsvReader::new(PlRefPath::new("data/debilt_2023_temps.csv"))
85 .with_has_header(true)
86 .with_try_parse_dates(true)
87 .finish()
88 .unwrap()
89 .with_columns(vec![
90 (col("tavg") / lit(10)).alias("avg"),
91 (col("tmin") / lit(10)).alias("min"),
92 (col("tmax") / lit(10)).alias("max"),
93 ])
94 .collect()
95 .unwrap();
96
97 let plot3 = TimeSeriesPlot::builder()
98 .data(&dataset3)
99 .x("date")
100 .y("avg")
101 .additional_series(vec!["min", "max"])
102 .colors(vec![Rgb(128, 128, 128), Rgb(0, 122, 255), Rgb(255, 128, 0)])
103 .lines(vec![Line::Solid, Line::Dot, Line::Dot])
104 .plot_title(Text::from("Time Series Plot").x(-0.05).y(1.35).size(14))
105 .y_title(Text::from("temperature (ºC)").x(-0.055).y(0.6))
106 .legend(&Legend::new().x(0.9).y(1.25))
107 .build();
108
109 let plot4 = BoxPlot::builder()
110 .data(&dataset2)
111 .labels("species")
112 .values("body_mass_g")
113 .orientation(Orientation::Vertical)
114 .group("gender")
115 .box_points(true)
116 .point_offset(-1.5)
117 .jitter(0.01)
118 .opacity(0.1)
119 .colors(vec![Rgb(0, 191, 255), Rgb(57, 255, 20), Rgb(255, 105, 180)])
120 .plot_title(Text::from("Box Plot").x(-0.075).y(1.35).size(14))
121 .x_title(Text::from("species").y(-0.3))
122 .y_title(Text::from("body mass (g)").x(-0.08).y(0.5))
123 .legend_title(Text::from("gender").size(12))
124 .y_axis(&Axis::new().value_thousands(true))
125 .legend(&Legend::new().x(1.0))
126 .build();
127
128 SubplotGrid::regular()
129 .plots(vec![&plot1, &plot2, &plot3, &plot4])
130 .rows(2)
131 .cols(2)
132 .v_gap(0.4)
133 .title(
134 Text::from("Regular Subplot Grid")
135 .size(16)
136 .font("Arial bold")
137 .y(0.95),
138 )
139 .build()
140 .plot();
141}
142
143fn irregular_grid_example() {
144 let dataset1 = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
145 .finish()
146 .unwrap()
147 .select([
148 col("species"),
149 col("sex").alias("gender"),
150 col("flipper_length_mm").cast(DataType::Int16),
151 col("body_mass_g").cast(DataType::Int16),
152 ])
153 .collect()
154 .unwrap();
155
156 let axis = Axis::new()
157 .show_line(true)
158 .show_grid(true)
159 .value_thousands(true)
160 .tick_direction(TickDirection::OutSide);
161
162 let plot1 = Histogram::builder()
163 .data(&dataset1)
164 .x("body_mass_g")
165 .group("species")
166 .opacity(0.5)
167 .colors(vec![Rgb(255, 165, 0), Rgb(147, 112, 219), Rgb(46, 139, 87)])
168 .plot_title(Text::from("Histogram").x(0.0).y(1.35).size(14))
169 .x_title(Text::from("body mass (g)").x(0.94).y(-0.35))
170 .y_title(Text::from("count").x(-0.062).y(0.83))
171 .x_axis(&axis)
172 .y_axis(&axis)
173 .legend_title(Text::from("species"))
174 .legend(&Legend::new().x(0.87).y(1.2))
175 .build();
176
177 let dataset2 = LazyCsvReader::new(PlRefPath::new("data/stock_prices.csv"))
178 .finish()
179 .unwrap()
180 .collect()
181 .unwrap();
182
183 let increasing = Direction::new()
184 .line_color(Rgb(0, 200, 100))
185 .line_width(0.5);
186
187 let decreasing = Direction::new()
188 .line_color(Rgb(200, 50, 50))
189 .line_width(0.5);
190
191 let plot2 = CandlestickPlot::builder()
192 .data(&dataset2)
193 .dates("date")
194 .open("open")
195 .high("high")
196 .low("low")
197 .close("close")
198 .increasing(&increasing)
199 .decreasing(&decreasing)
200 .whisker_width(0.1)
201 .plot_title(Text::from("Candlestick").x(0.0).y(1.35).size(14))
202 .y_title(Text::from("price ($)").x(-0.06).y(0.76))
203 .y_axis(&Axis::new().show_axis(true).show_grid(true))
204 .build();
205
206 let dataset3 = LazyCsvReader::new(PlRefPath::new("data/heatmap.csv"))
207 .finish()
208 .unwrap()
209 .collect()
210 .unwrap();
211
212 let plot3 = HeatMap::builder()
213 .data(&dataset3)
214 .x("x")
215 .y("y")
216 .z("z")
217 .color_bar(
218 &ColorBar::new()
219 .value_exponent(ValueExponent::None)
220 .separate_thousands(true)
221 .tick_length(5)
222 .tick_step(5000.0),
223 )
224 .plot_title(Text::from("Heat Map").x(0.0).y(1.35).size(14))
225 .color_scale(Palette::Viridis)
226 .build();
227
228 SubplotGrid::irregular()
229 .plots(vec![
230 (&plot1, 0, 0, 1, 1),
231 (&plot2, 0, 1, 1, 1),
232 (&plot3, 1, 0, 1, 2),
233 ])
234 .rows(2)
235 .cols(2)
236 .v_gap(0.35)
237 .h_gap(0.05)
238 .title(
239 Text::from("Irregular Subplot Grid")
240 .size(16)
241 .font("Arial bold")
242 .y(0.95),
243 )
244 .build()
245 .plot();
246}
247
248fn mixed_grid_example() {
249 // 2D cartesian scatter (baseline)
250 let penguins = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
251 .finish()
252 .unwrap()
253 .collect()
254 .unwrap()
255 .lazy()
256 .select([
257 col("species"),
258 col("bill_length_mm"),
259 col("flipper_length_mm"),
260 col("body_mass_g"),
261 ])
262 .collect()
263 .unwrap();
264
265 let scatter_2d = ScatterPlot::builder()
266 .data(&penguins)
267 .x("bill_length_mm")
268 .y("flipper_length_mm")
269 .group("species")
270 .opacity(0.65)
271 .size(10)
272 .plot_title(Text::from("Penguins 2D").y(1.3))
273 .build();
274
275 // 3D scene subplot
276 let scatter_3d = Scatter3dPlot::builder()
277 .data(&penguins)
278 .x("bill_length_mm")
279 .y("flipper_length_mm")
280 .z("body_mass_g")
281 .group("species")
282 .opacity(0.35)
283 .size(6)
284 .plot_title(Text::from("Penguins 3D").y(1.45))
285 .build();
286
287 // Polar subplot
288 let polar_df = LazyCsvReader::new(PlRefPath::new("data/product_comparison_polar.csv"))
289 .finish()
290 .unwrap()
291 .collect()
292 .unwrap();
293
294 let polar = ScatterPolar::builder()
295 .data(&polar_df)
296 .theta("angle")
297 .r("score")
298 .group("product")
299 .mode(Mode::LinesMarkers)
300 .size(10)
301 .plot_title(Text::from("Product Comparison (Polar)").y(1.5).x(0.72))
302 .legend(&Legend::new().x(0.8))
303 .build();
304
305 // Domain-based subplot (Sankey)
306 let sankey_df = LazyCsvReader::new(PlRefPath::new("data/energy_transition.csv"))
307 .finish()
308 .unwrap()
309 .collect()
310 .unwrap();
311
312 let sankey = SankeyDiagram::builder()
313 .data(&sankey_df)
314 .sources("source")
315 .targets("target")
316 .values("value")
317 .orientation(Orientation::Horizontal)
318 .arrangement(Arrangement::Freeform)
319 .plot_title(Text::from("Energy Flow").y(1.2))
320 .build();
321
322 // Mapbox subplot
323 let map_df = LazyCsvReader::new(PlRefPath::new("data/cities.csv"))
324 .finish()
325 .unwrap()
326 .collect()
327 .unwrap();
328
329 let scatter_map = ScatterMap::builder()
330 .data(&map_df)
331 .latitude("latitude")
332 .longitude("longitude")
333 .group("city")
334 .zoom(4)
335 .center([50.0, 5.0])
336 .opacity(0.8)
337 .plot_title(Text::from("Cities (Mapbox)").y(1.2))
338 .build();
339
340 // Geo subplot
341 let geo_df = LazyCsvReader::new(PlRefPath::new("data/world_cities.csv"))
342 .finish()
343 .unwrap()
344 .collect()
345 .unwrap();
346
347 let scatter_geo = ScatterGeo::builder()
348 .data(&geo_df)
349 .lat("lat")
350 .lon("lon")
351 .group("continent")
352 .mode(Mode::Markers)
353 .size(10)
354 .color(Rgb(255, 140, 0))
355 .shape(Shape::Circle)
356 .plot_title(Text::from("Global Cities (Geo)").x(0.65).y(1.2))
357 .legend(&Legend::new().x(0.8))
358 .build();
359
360 SubplotGrid::regular()
361 .plots(vec![
362 &scatter_2d,
363 &scatter_3d,
364 &polar,
365 &sankey,
366 &scatter_map,
367 &scatter_geo,
368 ])
369 .rows(2)
370 .cols(3)
371 .h_gap(0.12)
372 .v_gap(0.22)
373 .title(
374 Text::from("Mixed Subplot Grid")
375 .size(16)
376 .font("Arial bold")
377 .y(0.95),
378 )
379 .build()
380 .plot();
381}More examples
7fn main() {
8 let penguins_dataset = LazyCsvReader::new(PlRefPath::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(PlRefPath::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(PlRefPath::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_title(Text::from("Measure").size(12))
58 .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}Sourcepub fn irregular<'f1, 'f2>() -> SubplotGridIrregularBuilder<'f1, 'f2>
pub fn irregular<'f1, 'f2>() -> SubplotGridIrregularBuilder<'f1, 'f2>
Creates an irregular grid subplot layout with custom row/column spanning.
Allows plots to span multiple rows and/or columns, enabling dashboard-style layouts and asymmetric grid arrangements. Each plot explicitly specifies its position and span.
§Arguments
plots- Vector of tuples(plot, row, col, rowspan, colspan)where:plot: Reference to the plotrow: Starting row (0-indexed)col: Starting column (0-indexed)rowspan: Number of rows to span (minimum 1)colspan: Number of columns to span (minimum 1)
rows- Total number of rows in the grid (default: 1).cols- Total number of columns in the grid (default: 1).title- Overall title for the subplot figure (optional).h_gap- Horizontal spacing between columns (range: 0.0 to 1.0, default: 0.1).v_gap- Vertical spacing between rows (range: 0.0 to 1.0, default: 0.1).
§Example
use plotlars::{
Axis, CandlestickPlot, ColorBar, Direction, HeatMap, Histogram, Legend, Palette, Plot,
Rgb, SubplotGrid, Text, TickDirection, ValueExponent,
};
use polars::prelude::*;
let dataset1 = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
.finish()
.unwrap()
.select([
col("species"),
col("sex").alias("gender"),
col("flipper_length_mm").cast(DataType::Int16),
col("body_mass_g").cast(DataType::Int16),
])
.collect()
.unwrap();
let axis = Axis::new()
.show_line(true)
.show_grid(true)
.value_thousands(true)
.tick_direction(TickDirection::OutSide);
let plot1 = Histogram::builder()
.data(&dataset1)
.x("body_mass_g")
.group("species")
.opacity(0.5)
.colors(vec![Rgb(255, 165, 0), Rgb(147, 112, 219), Rgb(46, 139, 87)])
.plot_title(Text::from("Histogram").x(0.0).y(1.35).size(14))
.x_title(Text::from("body mass (g)").x(0.94).y(-0.35))
.y_title(Text::from("count").x(-0.062).y(0.83))
.x_axis(&axis)
.y_axis(&axis)
.legend_title(Text::from("species"))
.legend(&Legend::new().x(0.87).y(1.2))
.build();
let dataset2 = LazyCsvReader::new(PlRefPath::new("data/stock_prices.csv"))
.finish()
.unwrap()
.collect()
.unwrap();
let increasing = Direction::new()
.line_color(Rgb(0, 200, 100))
.line_width(0.5);
let decreasing = Direction::new()
.line_color(Rgb(200, 50, 50))
.line_width(0.5);
let plot2 = CandlestickPlot::builder()
.data(&dataset2)
.dates("date")
.open("open")
.high("high")
.low("low")
.close("close")
.increasing(&increasing)
.decreasing(&decreasing)
.whisker_width(0.1)
.plot_title(Text::from("Candlestick").x(0.0).y(1.35).size(14))
.y_title(Text::from("Price ($)").x(-0.06).y(0.76))
.y_axis(&Axis::new().show_axis(true).show_grid(true))
.build();
let dataset3 = LazyCsvReader::new(PlRefPath::new("data/heatmap.csv"))
.finish()
.unwrap()
.collect()
.unwrap();
let plot3 = HeatMap::builder()
.data(&dataset3)
.x("x")
.y("y")
.z("z")
.color_bar(
&ColorBar::new()
.value_exponent(ValueExponent::None)
.separate_thousands(true)
.tick_length(5)
.tick_step(5000.0),
)
.plot_title(Text::from("Heat Map").x(0.0).y(1.35).size(14))
.color_scale(Palette::Viridis)
.build();
SubplotGrid::irregular()
.plots(vec![
(&plot1, 0, 0, 1, 1),
(&plot2, 0, 1, 1, 1),
(&plot3, 1, 0, 1, 2),
])
.rows(2)
.cols(2)
.v_gap(0.35)
.h_gap(0.05)
.title(
Text::from("Irregular Subplot Grid")
.size(16)
.font("Arial bold")
.y(0.95),
)
.build()
.plot();
Examples found in repository?
143fn irregular_grid_example() {
144 let dataset1 = LazyCsvReader::new(PlRefPath::new("data/penguins.csv"))
145 .finish()
146 .unwrap()
147 .select([
148 col("species"),
149 col("sex").alias("gender"),
150 col("flipper_length_mm").cast(DataType::Int16),
151 col("body_mass_g").cast(DataType::Int16),
152 ])
153 .collect()
154 .unwrap();
155
156 let axis = Axis::new()
157 .show_line(true)
158 .show_grid(true)
159 .value_thousands(true)
160 .tick_direction(TickDirection::OutSide);
161
162 let plot1 = Histogram::builder()
163 .data(&dataset1)
164 .x("body_mass_g")
165 .group("species")
166 .opacity(0.5)
167 .colors(vec![Rgb(255, 165, 0), Rgb(147, 112, 219), Rgb(46, 139, 87)])
168 .plot_title(Text::from("Histogram").x(0.0).y(1.35).size(14))
169 .x_title(Text::from("body mass (g)").x(0.94).y(-0.35))
170 .y_title(Text::from("count").x(-0.062).y(0.83))
171 .x_axis(&axis)
172 .y_axis(&axis)
173 .legend_title(Text::from("species"))
174 .legend(&Legend::new().x(0.87).y(1.2))
175 .build();
176
177 let dataset2 = LazyCsvReader::new(PlRefPath::new("data/stock_prices.csv"))
178 .finish()
179 .unwrap()
180 .collect()
181 .unwrap();
182
183 let increasing = Direction::new()
184 .line_color(Rgb(0, 200, 100))
185 .line_width(0.5);
186
187 let decreasing = Direction::new()
188 .line_color(Rgb(200, 50, 50))
189 .line_width(0.5);
190
191 let plot2 = CandlestickPlot::builder()
192 .data(&dataset2)
193 .dates("date")
194 .open("open")
195 .high("high")
196 .low("low")
197 .close("close")
198 .increasing(&increasing)
199 .decreasing(&decreasing)
200 .whisker_width(0.1)
201 .plot_title(Text::from("Candlestick").x(0.0).y(1.35).size(14))
202 .y_title(Text::from("price ($)").x(-0.06).y(0.76))
203 .y_axis(&Axis::new().show_axis(true).show_grid(true))
204 .build();
205
206 let dataset3 = LazyCsvReader::new(PlRefPath::new("data/heatmap.csv"))
207 .finish()
208 .unwrap()
209 .collect()
210 .unwrap();
211
212 let plot3 = HeatMap::builder()
213 .data(&dataset3)
214 .x("x")
215 .y("y")
216 .z("z")
217 .color_bar(
218 &ColorBar::new()
219 .value_exponent(ValueExponent::None)
220 .separate_thousands(true)
221 .tick_length(5)
222 .tick_step(5000.0),
223 )
224 .plot_title(Text::from("Heat Map").x(0.0).y(1.35).size(14))
225 .color_scale(Palette::Viridis)
226 .build();
227
228 SubplotGrid::irregular()
229 .plots(vec![
230 (&plot1, 0, 0, 1, 1),
231 (&plot2, 0, 1, 1, 1),
232 (&plot3, 1, 0, 1, 2),
233 ])
234 .rows(2)
235 .cols(2)
236 .v_gap(0.35)
237 .h_gap(0.05)
238 .title(
239 Text::from("Irregular Subplot Grid")
240 .size(16)
241 .font("Arial bold")
242 .y(0.95),
243 )
244 .build()
245 .plot();
246}Trait Implementations§
Source§impl Clone for SubplotGrid
impl Clone for SubplotGrid
Source§fn clone(&self) -> SubplotGrid
fn clone(&self) -> SubplotGrid
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for SubplotGrid
impl !RefUnwindSafe for SubplotGrid
impl !Send for SubplotGrid
impl !Sync for SubplotGrid
impl Unpin for SubplotGrid
impl !UnwindSafe for SubplotGrid
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more