Skip to content

Add axis range bounds support #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/book/src/recipes/basic_charts/line_charts.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,13 @@ The `to_inline_html` method is used to produce the html plot displayed in this p
{{#include ../../../../../examples/basic_charts/src/main.rs:filled_lines}}
```

{{#include ../../../../../examples/basic_charts/output/inline_filled_lines.html}}
{{#include ../../../../../examples/basic_charts/output/inline_filled_lines.html}}

## Setting Lower or Upper Bounds on Axis
This example demonstrates how to set partial axis ranges using both the new `AxisRange` API and the backward-compatible vector syntax. The x-axis uses both the new `AxisRange::upper()` method and the traditional `vec![None, Some(value)]` syntax to set only an upper bound, while the y-axis uses only the `vec![Some(value), None]` syntax to set a lower bound.

```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:set_lower_or_upper_bound_on_axis}}
```

{{#include ../../../../../examples/basic_charts/output/inline_set_lower_or_upper_bound_on_axis.html}}
1 change: 1 addition & 0 deletions examples/basic_charts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ plotly = { path = "../../plotly" }
plotly_utils = { path = "../plotly_utils" }
rand = "0.9"
rand_distr = "0.5"
csv = "1.3"
151 changes: 151 additions & 0 deletions examples/basic_charts/assets/iris.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,setosa
4.9,3.0,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5.0,3.6,1.4,0.2,setosa
5.4,3.9,1.7,0.4,setosa
4.6,3.4,1.4,0.3,setosa
5.0,3.4,1.5,0.2,setosa
4.4,2.9,1.4,0.2,setosa
4.9,3.1,1.5,0.1,setosa
5.4,3.7,1.5,0.2,setosa
4.8,3.4,1.6,0.2,setosa
4.8,3.0,1.4,0.1,setosa
4.3,3.0,1.1,0.1,setosa
5.8,4.0,1.2,0.2,setosa
5.7,4.4,1.5,0.4,setosa
5.4,3.9,1.3,0.4,setosa
5.1,3.5,1.4,0.3,setosa
5.7,3.8,1.7,0.3,setosa
5.1,3.8,1.5,0.3,setosa
5.4,3.4,1.7,0.2,setosa
5.1,3.7,1.5,0.4,setosa
4.6,3.6,1.0,0.2,setosa
5.1,3.3,1.7,0.5,setosa
4.8,3.4,1.9,0.2,setosa
5.0,3.0,1.6,0.2,setosa
5.0,3.4,1.6,0.4,setosa
5.2,3.5,1.5,0.2,setosa
5.2,3.4,1.4,0.2,setosa
4.7,3.2,1.6,0.2,setosa
4.8,3.1,1.6,0.2,setosa
5.4,3.4,1.5,0.4,setosa
5.2,4.1,1.5,0.1,setosa
5.5,4.2,1.4,0.2,setosa
4.9,3.1,1.5,0.2,setosa
5.0,3.2,1.2,0.2,setosa
5.5,3.5,1.3,0.2,setosa
4.9,3.6,1.4,0.1,setosa
4.4,3.0,1.3,0.2,setosa
5.1,3.4,1.5,0.2,setosa
5.0,3.5,1.3,0.3,setosa
4.5,2.3,1.3,0.3,setosa
4.4,3.2,1.3,0.2,setosa
5.0,3.5,1.6,0.6,setosa
5.1,3.8,1.9,0.4,setosa
4.8,3.0,1.4,0.3,setosa
5.1,3.8,1.6,0.2,setosa
4.6,3.2,1.4,0.2,setosa
5.3,3.7,1.5,0.2,setosa
5.0,3.3,1.4,0.2,setosa
7.0,3.2,4.7,1.4,versicolor
6.4,3.2,4.5,1.5,versicolor
6.9,3.1,4.9,1.5,versicolor
5.5,2.3,4.0,1.3,versicolor
6.5,2.8,4.6,1.5,versicolor
5.7,2.8,4.5,1.3,versicolor
6.3,3.3,4.7,1.6,versicolor
4.9,2.4,3.3,1.0,versicolor
6.6,2.9,4.6,1.3,versicolor
5.2,2.7,3.9,1.4,versicolor
5.0,2.0,3.5,1.0,versicolor
5.9,3.0,4.2,1.5,versicolor
6.0,2.2,4.0,1.0,versicolor
6.1,2.9,4.7,1.4,versicolor
5.6,2.9,3.6,1.3,versicolor
6.7,3.1,4.4,1.4,versicolor
5.6,3.0,4.5,1.5,versicolor
5.8,2.7,4.1,1.0,versicolor
6.2,2.2,4.5,1.5,versicolor
5.6,2.5,3.9,1.1,versicolor
5.9,3.2,4.8,1.8,versicolor
6.1,2.8,4.0,1.3,versicolor
6.3,2.5,4.9,1.5,versicolor
6.1,2.8,4.7,1.2,versicolor
6.4,2.9,4.3,1.3,versicolor
6.6,3.0,4.4,1.4,versicolor
6.8,2.8,4.8,1.4,versicolor
6.7,3.0,5.0,1.7,versicolor
6.0,2.9,4.5,1.5,versicolor
5.7,2.6,3.5,1.0,versicolor
5.5,2.4,3.8,1.1,versicolor
5.5,2.4,3.7,1.0,versicolor
5.8,2.7,3.9,1.2,versicolor
6.0,2.7,5.1,1.6,versicolor
5.4,3.0,4.5,1.5,versicolor
6.0,3.4,4.5,1.6,versicolor
6.7,3.1,4.7,1.5,versicolor
6.3,2.3,4.4,1.3,versicolor
5.6,3.0,4.1,1.3,versicolor
5.5,2.5,4.0,1.3,versicolor
5.5,2.6,4.4,1.2,versicolor
6.1,3.0,4.6,1.4,versicolor
5.8,2.6,4.0,1.2,versicolor
5.0,2.3,3.3,1.0,versicolor
5.6,2.7,4.2,1.3,versicolor
5.7,3.0,4.2,1.2,versicolor
5.7,2.9,4.2,1.3,versicolor
6.2,2.9,4.3,1.3,versicolor
5.1,2.5,3.0,1.1,versicolor
5.7,2.8,4.1,1.3,versicolor
6.3,3.3,6.0,2.5,virginica
5.8,2.7,5.1,1.9,virginica
7.1,3.0,5.9,2.1,virginica
6.3,2.9,5.6,1.8,virginica
6.5,3.0,5.8,2.2,virginica
7.6,3.0,6.6,2.1,virginica
4.9,2.5,4.5,1.7,virginica
7.3,2.9,6.3,1.8,virginica
6.7,2.5,5.8,1.8,virginica
7.2,3.6,6.1,2.5,virginica
6.5,3.2,5.1,2.0,virginica
6.4,2.7,5.3,1.9,virginica
6.8,3.0,5.5,2.1,virginica
5.7,2.5,5.0,2.0,virginica
5.8,2.8,5.1,2.4,virginica
6.4,3.2,5.3,2.3,virginica
6.5,3.0,5.5,1.8,virginica
7.7,3.8,6.7,2.2,virginica
7.7,2.6,6.9,2.3,virginica
6.0,2.2,5.0,1.5,virginica
6.9,3.2,5.7,2.3,virginica
5.6,2.8,4.9,2.0,virginica
7.7,2.8,6.7,2.0,virginica
6.3,2.7,4.9,1.8,virginica
6.7,3.3,5.7,2.1,virginica
7.2,3.2,6.0,1.8,virginica
6.2,2.8,4.8,1.8,virginica
6.1,3.0,4.9,1.8,virginica
6.4,2.8,5.6,2.1,virginica
7.2,3.0,5.8,1.6,virginica
7.4,2.8,6.1,1.9,virginica
7.9,3.8,6.4,2.0,virginica
6.4,2.8,5.6,2.2,virginica
6.3,2.8,5.1,1.5,virginica
6.1,2.6,5.6,1.4,virginica
7.7,3.0,6.1,2.3,virginica
6.3,3.4,5.6,2.4,virginica
6.4,3.1,5.5,1.8,virginica
6.0,3.0,4.8,1.8,virginica
6.9,3.1,5.4,2.1,virginica
6.7,3.1,5.6,2.4,virginica
6.9,3.1,5.1,2.3,virginica
5.8,2.7,5.1,1.9,virginica
6.8,3.2,5.9,2.3,virginica
6.7,3.3,5.7,2.5,virginica
6.7,3.0,5.2,2.3,virginica
6.3,2.5,5.0,1.9,virginica
6.5,3.0,5.2,2.0,virginica
6.2,3.4,5.4,2.3,virginica
5.9,3.0,5.1,1.8,virginica
121 changes: 118 additions & 3 deletions examples/basic_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use plotly::{
Marker, Mode, Orientation, Pattern, PatternShape,
},
layout::{
Annotation, Axis, BarMode, CategoryOrder, Layout, LayoutGrid, Legend, TicksDirection,
TraceOrder,
Annotation, Axis, AxisRange, BarMode, CategoryOrder, Layout, LayoutGrid, Legend,
TicksDirection, TraceOrder,
},
sankey::{Line as SankeyLine, Link, Node},
traces::table::{Cells, Header},
Expand Down Expand Up @@ -997,6 +997,119 @@ fn grouped_donout_pie_charts(show: bool, file_name: &str) {
}
// ANCHOR_END: grouped_donout_pie_charts

// ANCHOR: set_lower_or_upper_bound_on_axis
fn set_lower_or_upper_bound_on_axis(show: bool, file_name: &str) {
use std::fs::File;
use std::io::BufReader;

// Read the iris dataset
let file = File::open("assets/iris.csv").expect("Failed to open iris.csv");
let reader = BufReader::new(file);
let mut csv_reader = csv::Reader::from_reader(reader);

// Parse the data
let mut sepal_width = Vec::new();
let mut sepal_length = Vec::new();
let mut species = Vec::new();

for result in csv_reader.records() {
let record = result.expect("Failed to read CSV record");
sepal_width.push(record[1].parse::<f64>().unwrap());
sepal_length.push(record[0].parse::<f64>().unwrap());
species.push(record[4].to_string());
}

// Create separate traces for each species
let mut traces = Vec::new();
let unique_species: Vec<String> = species
.iter()
.cloned()
.collect::<std::collections::HashSet<_>>()
.into_iter()
.collect();

for (i, species_name) in unique_species.iter().enumerate() {
let mut x = Vec::new();
let mut y = Vec::new();

for (j, s) in species.iter().enumerate() {
if s == species_name {
x.push(sepal_width[j]);
y.push(sepal_length[j]);
}
}

let trace = Scatter::new(x, y)
.name(species_name)
.mode(plotly::common::Mode::Markers)
.x_axis(format!("x{}", i + 1))
.y_axis(format!("y{}", i + 1));
traces.push(trace);
}

let mut plot = Plot::new();
for trace in traces {
plot.add_trace(trace);
}

// Create layout with subplots
let mut layout = Layout::new()
.title("Iris Dataset - Subplots by Species")
.grid(
LayoutGrid::new()
.rows(1)
.columns(3)
.pattern(plotly::layout::GridPattern::Independent),
);

// Set x-axis range for all subplots: [None, 4.5]
layout = layout
.x_axis(
Axis::new()
.title("sepal_width")
// Can be set using a vec! of two optional values
.range(vec![None, Some(4.5)]),
)
.x_axis2(
Axis::new()
.title("sepal_width")
// Or can be set using AxisRange::upper(4.5)
.range(AxisRange::upper(4.5)),
)
.x_axis3(
Axis::new()
.title("sepal_width")
// Or can be set using AxisRange::upper(4.5)
.range(AxisRange::upper(4.5)),
);

// Set y-axis range for all subplots: [3, None]
layout = layout
.y_axis(
Axis::new()
.title("sepal_length")
.range(vec![Some(3.0), None]),
)
.y_axis2(
Axis::new()
.title("sepal_length")
.range(vec![Some(3.0), None]),
)
.y_axis3(
Axis::new()
.title("sepal_length")
.range(vec![Some(3.0), None]),
);

plot.set_layout(layout);

let path = write_example_to_html(&plot, file_name);
if show {
plot.show_html(path);
}
}
// ANCHOR_END: set_lower_or_upper_bound_on_axis

fn main() {
// Change false to true on any of these lines to display the example.

Expand All @@ -1013,7 +1126,6 @@ fn main() {
categories_scatter_chart(false, "categories_scatter_chart");

// Line Charts

adding_names_to_line_and_scatter_plot(false, "adding_names_to_line_and_scatter_plot");
line_and_scatter_styling(false, "line_and_scatter_styling");
styling_line_plot(false, "styling_line_plot");
Expand Down Expand Up @@ -1041,4 +1153,7 @@ fn main() {
pie_chart_text_control(false, "pie_chart_text_control");

grouped_donout_pie_charts(false, "grouped_donout_pie_charts");

// Set Lower or Upper Bound on Axis
set_lower_or_upper_bound_on_axis(false, "set_lower_or_upper_bound_on_axis");
}
Loading
Loading