Skip to content

Commit 6c89daa

Browse files
committed
add support for optional axis range bounds
Signed-off-by: Andrei Gherghescu <[email protected]>
1 parent c729b73 commit 6c89daa

File tree

8 files changed

+346
-87
lines changed

8 files changed

+346
-87
lines changed

examples/basic_charts/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ plotly = { path = "../../plotly" }
1010
plotly_utils = { path = "../plotly_utils" }
1111
rand = "0.9"
1212
rand_distr = "0.5"
13+
csv = "1.3"

examples/basic_charts/assets/iris.csv

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
sepal_length,sepal_width,petal_length,petal_width,species
2+
5.1,3.5,1.4,0.2,setosa
3+
4.9,3.0,1.4,0.2,setosa
4+
4.7,3.2,1.3,0.2,setosa
5+
4.6,3.1,1.5,0.2,setosa
6+
5.0,3.6,1.4,0.2,setosa
7+
5.4,3.9,1.7,0.4,setosa
8+
4.6,3.4,1.4,0.3,setosa
9+
5.0,3.4,1.5,0.2,setosa
10+
4.4,2.9,1.4,0.2,setosa
11+
4.9,3.1,1.5,0.1,setosa
12+
5.4,3.7,1.5,0.2,setosa
13+
4.8,3.4,1.6,0.2,setosa
14+
4.8,3.0,1.4,0.1,setosa
15+
4.3,3.0,1.1,0.1,setosa
16+
5.8,4.0,1.2,0.2,setosa
17+
5.7,4.4,1.5,0.4,setosa
18+
5.4,3.9,1.3,0.4,setosa
19+
5.1,3.5,1.4,0.3,setosa
20+
5.7,3.8,1.7,0.3,setosa
21+
5.1,3.8,1.5,0.3,setosa
22+
5.4,3.4,1.7,0.2,setosa
23+
5.1,3.7,1.5,0.4,setosa
24+
4.6,3.6,1.0,0.2,setosa
25+
5.1,3.3,1.7,0.5,setosa
26+
4.8,3.4,1.9,0.2,setosa
27+
5.0,3.0,1.6,0.2,setosa
28+
5.0,3.4,1.6,0.4,setosa
29+
5.2,3.5,1.5,0.2,setosa
30+
5.2,3.4,1.4,0.2,setosa
31+
4.7,3.2,1.6,0.2,setosa
32+
4.8,3.1,1.6,0.2,setosa
33+
5.4,3.4,1.5,0.4,setosa
34+
5.2,4.1,1.5,0.1,setosa
35+
5.5,4.2,1.4,0.2,setosa
36+
4.9,3.1,1.5,0.2,setosa
37+
5.0,3.2,1.2,0.2,setosa
38+
5.5,3.5,1.3,0.2,setosa
39+
4.9,3.6,1.4,0.1,setosa
40+
4.4,3.0,1.3,0.2,setosa
41+
5.1,3.4,1.5,0.2,setosa
42+
5.0,3.5,1.3,0.3,setosa
43+
4.5,2.3,1.3,0.3,setosa
44+
4.4,3.2,1.3,0.2,setosa
45+
5.0,3.5,1.6,0.6,setosa
46+
5.1,3.8,1.9,0.4,setosa
47+
4.8,3.0,1.4,0.3,setosa
48+
5.1,3.8,1.6,0.2,setosa
49+
4.6,3.2,1.4,0.2,setosa
50+
5.3,3.7,1.5,0.2,setosa
51+
5.0,3.3,1.4,0.2,setosa
52+
7.0,3.2,4.7,1.4,versicolor
53+
6.4,3.2,4.5,1.5,versicolor
54+
6.9,3.1,4.9,1.5,versicolor
55+
5.5,2.3,4.0,1.3,versicolor
56+
6.5,2.8,4.6,1.5,versicolor
57+
5.7,2.8,4.5,1.3,versicolor
58+
6.3,3.3,4.7,1.6,versicolor
59+
4.9,2.4,3.3,1.0,versicolor
60+
6.6,2.9,4.6,1.3,versicolor
61+
5.2,2.7,3.9,1.4,versicolor
62+
5.0,2.0,3.5,1.0,versicolor
63+
5.9,3.0,4.2,1.5,versicolor
64+
6.0,2.2,4.0,1.0,versicolor
65+
6.1,2.9,4.7,1.4,versicolor
66+
5.6,2.9,3.6,1.3,versicolor
67+
6.7,3.1,4.4,1.4,versicolor
68+
5.6,3.0,4.5,1.5,versicolor
69+
5.8,2.7,4.1,1.0,versicolor
70+
6.2,2.2,4.5,1.5,versicolor
71+
5.6,2.5,3.9,1.1,versicolor
72+
5.9,3.2,4.8,1.8,versicolor
73+
6.1,2.8,4.0,1.3,versicolor
74+
6.3,2.5,4.9,1.5,versicolor
75+
6.1,2.8,4.7,1.2,versicolor
76+
6.4,2.9,4.3,1.3,versicolor
77+
6.6,3.0,4.4,1.4,versicolor
78+
6.8,2.8,4.8,1.4,versicolor
79+
6.7,3.0,5.0,1.7,versicolor
80+
6.0,2.9,4.5,1.5,versicolor
81+
5.7,2.6,3.5,1.0,versicolor
82+
5.5,2.4,3.8,1.1,versicolor
83+
5.5,2.4,3.7,1.0,versicolor
84+
5.8,2.7,3.9,1.2,versicolor
85+
6.0,2.7,5.1,1.6,versicolor
86+
5.4,3.0,4.5,1.5,versicolor
87+
6.0,3.4,4.5,1.6,versicolor
88+
6.7,3.1,4.7,1.5,versicolor
89+
6.3,2.3,4.4,1.3,versicolor
90+
5.6,3.0,4.1,1.3,versicolor
91+
5.5,2.5,4.0,1.3,versicolor
92+
5.5,2.6,4.4,1.2,versicolor
93+
6.1,3.0,4.6,1.4,versicolor
94+
5.8,2.6,4.0,1.2,versicolor
95+
5.0,2.3,3.3,1.0,versicolor
96+
5.6,2.7,4.2,1.3,versicolor
97+
5.7,3.0,4.2,1.2,versicolor
98+
5.7,2.9,4.2,1.3,versicolor
99+
6.2,2.9,4.3,1.3,versicolor
100+
5.1,2.5,3.0,1.1,versicolor
101+
5.7,2.8,4.1,1.3,versicolor
102+
6.3,3.3,6.0,2.5,virginica
103+
5.8,2.7,5.1,1.9,virginica
104+
7.1,3.0,5.9,2.1,virginica
105+
6.3,2.9,5.6,1.8,virginica
106+
6.5,3.0,5.8,2.2,virginica
107+
7.6,3.0,6.6,2.1,virginica
108+
4.9,2.5,4.5,1.7,virginica
109+
7.3,2.9,6.3,1.8,virginica
110+
6.7,2.5,5.8,1.8,virginica
111+
7.2,3.6,6.1,2.5,virginica
112+
6.5,3.2,5.1,2.0,virginica
113+
6.4,2.7,5.3,1.9,virginica
114+
6.8,3.0,5.5,2.1,virginica
115+
5.7,2.5,5.0,2.0,virginica
116+
5.8,2.8,5.1,2.4,virginica
117+
6.4,3.2,5.3,2.3,virginica
118+
6.5,3.0,5.5,1.8,virginica
119+
7.7,3.8,6.7,2.2,virginica
120+
7.7,2.6,6.9,2.3,virginica
121+
6.0,2.2,5.0,1.5,virginica
122+
6.9,3.2,5.7,2.3,virginica
123+
5.6,2.8,4.9,2.0,virginica
124+
7.7,2.8,6.7,2.0,virginica
125+
6.3,2.7,4.9,1.8,virginica
126+
6.7,3.3,5.7,2.1,virginica
127+
7.2,3.2,6.0,1.8,virginica
128+
6.2,2.8,4.8,1.8,virginica
129+
6.1,3.0,4.9,1.8,virginica
130+
6.4,2.8,5.6,2.1,virginica
131+
7.2,3.0,5.8,1.6,virginica
132+
7.4,2.8,6.1,1.9,virginica
133+
7.9,3.8,6.4,2.0,virginica
134+
6.4,2.8,5.6,2.2,virginica
135+
6.3,2.8,5.1,1.5,virginica
136+
6.1,2.6,5.6,1.4,virginica
137+
7.7,3.0,6.1,2.3,virginica
138+
6.3,3.4,5.6,2.4,virginica
139+
6.4,3.1,5.5,1.8,virginica
140+
6.0,3.0,4.8,1.8,virginica
141+
6.9,3.1,5.4,2.1,virginica
142+
6.7,3.1,5.6,2.4,virginica
143+
6.9,3.1,5.1,2.3,virginica
144+
5.8,2.7,5.1,1.9,virginica
145+
6.8,3.2,5.9,2.3,virginica
146+
6.7,3.3,5.7,2.5,virginica
147+
6.7,3.0,5.2,2.3,virginica
148+
6.3,2.5,5.0,1.9,virginica
149+
6.5,3.0,5.2,2.0,virginica
150+
6.2,3.4,5.4,2.3,virginica
151+
5.9,3.0,5.1,1.8,virginica

examples/basic_charts/src/main.rs

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ fn data_labels_hover(show: bool, file_name: &str) {
142142

143143
let layout = Layout::new()
144144
.title("Data Labels Hover")
145-
.x_axis(Axis::new().title("x").range(vec![0.75, 5.25]))
146-
.y_axis(Axis::new().title("y").range(vec![0., 8.]));
145+
.x_axis(Axis::new().title("x").range(vec![0.75, 5.25].into()))
146+
.y_axis(Axis::new().title("y").range(vec![0., 8.].into()));
147147
plot.set_layout(layout);
148148

149149
let path = write_example_to_html(&plot, file_name);
@@ -172,8 +172,8 @@ fn data_labels_on_the_plot(show: bool, file_name: &str) {
172172

173173
let layout = Layout::new()
174174
.title("Data Labels on the Plot")
175-
.x_axis(Axis::new().range(vec![0.75, 5.25]))
176-
.y_axis(Axis::new().range(vec![0., 8.]));
175+
.x_axis(Axis::new().range(vec![0.75, 5.25].into()))
176+
.y_axis(Axis::new().range(vec![0., 8.].into()));
177177
plot.set_layout(layout);
178178

179179
let path = write_example_to_html(&plot, file_name);
@@ -482,8 +482,8 @@ fn line_dash(show: bool, file_name: &str) {
482482
.trace_order(TraceOrder::Reversed)
483483
.font(Font::new().size(16)),
484484
)
485-
.x_axis(Axis::new().range(vec![0.95, 5.05]).auto_range(false))
486-
.y_axis(Axis::new().range(vec![0.0, 28.5]).auto_range(false));
485+
.x_axis(Axis::new().range(vec![0.95, 5.05].into()).auto_range(false))
486+
.y_axis(Axis::new().range(vec![0.0, 28.5].into()).auto_range(false));
487487
plot.set_layout(layout);
488488
plot.add_trace(trace1);
489489
plot.add_trace(trace2);
@@ -564,7 +564,7 @@ fn filled_lines(show: bool, file_name: &str) {
564564
.x_axis(
565565
Axis::new()
566566
.grid_color(Rgb::new(255, 255, 255))
567-
.range(vec![1.0, 10.0])
567+
.range(vec![1.0, 10.0].into())
568568
.show_grid(true)
569569
.show_line(false)
570570
.show_tick_labels(true)
@@ -997,6 +997,97 @@ fn grouped_donout_pie_charts(show: bool, file_name: &str) {
997997
}
998998
// ANCHOR_END: grouped_donout_pie_charts
999999

1000+
// ANCHOR: iris_faceted_plot
1001+
fn iris_faceted_plot(show: bool, file_name: &str) {
1002+
use std::fs::File;
1003+
use std::io::BufReader;
1004+
1005+
// Read the iris dataset
1006+
let file = File::open("assets/iris.csv").expect("Failed to open iris.csv");
1007+
let reader = BufReader::new(file);
1008+
let mut csv_reader = csv::Reader::from_reader(reader);
1009+
1010+
// Parse the data
1011+
let mut sepal_width = Vec::new();
1012+
let mut sepal_length = Vec::new();
1013+
let mut species = Vec::new();
1014+
1015+
for result in csv_reader.records() {
1016+
let record = result.expect("Failed to read CSV record");
1017+
sepal_width.push(record[1].parse::<f64>().unwrap());
1018+
sepal_length.push(record[0].parse::<f64>().unwrap());
1019+
species.push(record[4].to_string());
1020+
}
1021+
1022+
// Create separate traces for each species (faceted plot)
1023+
let mut traces = Vec::new();
1024+
let unique_species: Vec<String> = species.iter().cloned().collect::<std::collections::HashSet<_>>().into_iter().collect();
1025+
1026+
for (i, species_name) in unique_species.iter().enumerate() {
1027+
let mut x = Vec::new();
1028+
let mut y = Vec::new();
1029+
1030+
for (j, s) in species.iter().enumerate() {
1031+
if s == species_name {
1032+
x.push(sepal_width[j]);
1033+
y.push(sepal_length[j]);
1034+
}
1035+
}
1036+
1037+
let trace = Scatter::new(x, y)
1038+
.name(species_name)
1039+
.mode(plotly::common::Mode::Markers)
1040+
.x_axis(format!("x{}", i + 1))
1041+
.y_axis(format!("y{}", i + 1));
1042+
traces.push(trace);
1043+
}
1044+
1045+
let mut plot = Plot::new();
1046+
for trace in traces {
1047+
plot.add_trace(trace);
1048+
}
1049+
1050+
// Create layout with subplots (faceted)
1051+
let mut layout = Layout::new()
1052+
.title("Iris Dataset - Faceted by Species")
1053+
.grid(LayoutGrid::new()
1054+
.rows(1)
1055+
.columns(3)
1056+
.pattern(plotly::layout::GridPattern::Independent));
1057+
1058+
// Set x-axis range for all subplots: [None, 4.5]
1059+
layout = layout
1060+
.x_axis(Axis::new()
1061+
.title("sepal_width")
1062+
.range(vec![None, Some(4.5)].into()))
1063+
.x_axis2(Axis::new()
1064+
.title("sepal_width")
1065+
.range(vec![None, Some(4.5)].into()))
1066+
.x_axis3(Axis::new()
1067+
.title("sepal_width")
1068+
.range(vec![None, Some(4.5)].into()));
1069+
1070+
// Set y-axis range for all subplots: [3, None]
1071+
layout = layout
1072+
.y_axis(Axis::new()
1073+
.title("sepal_length")
1074+
.range(vec![Some(3.0), None].into()))
1075+
.y_axis2(Axis::new()
1076+
.title("sepal_length")
1077+
.range(vec![Some(3.0), None].into()))
1078+
.y_axis3(Axis::new()
1079+
.title("sepal_length")
1080+
.range(vec![Some(3.0), None].into()));
1081+
1082+
plot.set_layout(layout);
1083+
1084+
let path = write_example_to_html(&plot, file_name);
1085+
if show {
1086+
plot.show_html(path);
1087+
}
1088+
}
1089+
// ANCHOR_END: iris_faceted_plot
1090+
10001091
fn main() {
10011092
// Change false to true on any of these lines to display the example.
10021093

@@ -1013,7 +1104,6 @@ fn main() {
10131104
categories_scatter_chart(false, "categories_scatter_chart");
10141105

10151106
// Line Charts
1016-
10171107
adding_names_to_line_and_scatter_plot(false, "adding_names_to_line_and_scatter_plot");
10181108
line_and_scatter_styling(false, "line_and_scatter_styling");
10191109
styling_line_plot(false, "styling_line_plot");
@@ -1041,4 +1131,7 @@ fn main() {
10411131
pie_chart_text_control(false, "pie_chart_text_control");
10421132

10431133
grouped_donout_pie_charts(false, "grouped_donout_pie_charts");
1134+
1135+
// Iris Faceted Plot with Partial Axis Ranges
1136+
iris_faceted_plot(false, "iris_faceted_plot");
10441137
}

examples/financial_charts/src/main.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use std::path::PathBuf;
66
use chrono::{DateTime, Duration};
77
use plotly::common::TickFormatStop;
88
use plotly::layout::{Axis, RangeSelector, RangeSlider, SelectorButton, SelectorStep, StepMode};
9-
use plotly::{Candlestick, Layout, Ohlc, Plot, Scatter};
9+
use plotly::{
10+
Candlestick, Layout, Ohlc, Plot, Scatter
11+
};
1012
use plotly_utils::write_example_to_html;
1113
use serde::Deserialize;
1214

@@ -52,7 +54,7 @@ fn time_series_plot_with_custom_date_range(show: bool, file_name: &str) {
5254
plot.add_trace(trace);
5355

5456
let layout = Layout::new()
55-
.x_axis(Axis::new().range(vec!["2016-07-01", "2016-12-31"]))
57+
.x_axis(Axis::new().range(vec!["2016-07-01", "2016-12-31"].into()))
5658
.title("Manually Set Date Range");
5759
plot.set_layout(layout);
5860

@@ -343,7 +345,7 @@ fn series_with_gaps_for_weekends_and_holidays(show: bool, file_name: &str) {
343345
.title("Series with Weekend and Holiday Gaps")
344346
.x_axis(
345347
Axis::new()
346-
.range(vec!["2015-12-01", "2016-01-15"])
348+
.range(vec!["2015-12-01", "2016-01-15"].into())
347349
.title("Date"),
348350
)
349351
.y_axis(Axis::new().title("Price"));
@@ -378,7 +380,7 @@ fn hiding_weekends_and_holidays_with_rangebreaks(show: bool, file_name: &str) {
378380
.title("Hide Weekend and Holiday Gaps with rangebreaks")
379381
.x_axis(
380382
Axis::new()
381-
.range(vec!["2015-12-01", "2016-01-15"])
383+
.range(vec!["2015-12-01", "2016-01-15"].into())
382384
.title("Date")
383385
.range_breaks(vec![
384386
plotly::layout::RangeBreak::new()

0 commit comments

Comments
 (0)