Line Charts
The following imports have been used to produce the plots below:
#![allow(unused)] fn main() { use ndarray::Array; use plotly::common::{ ColorScale, ColorScalePalette, DashType, Fill, Font, Line, LineShape, Marker, Mode, Title, }; use plotly::layout::{Axis, BarMode, Layout, Legend, TicksDirection}; use plotly::{Bar, color::{NamedColor, Rgb, Rgba}, Plot, Scatter}; use rand_distr::{Distribution, Normal, Uniform}; }
The to_inline_html
method is used to produce the html plot displayed in this page.
Adding Names to Line and Scatter Plot
#![allow(unused)] fn main() { fn adding_names_to_line_and_scatter_plot(show: bool, file_name: &str) { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![10, 15, 13, 17]) .mode(Mode::Markers) .name("Scatter"); let trace2 = Scatter::new(vec![2, 3, 4, 5], vec![16, 5, 11, 9]) .mode(Mode::Lines) .name("Lines"); let trace3 = Scatter::new(vec![1, 2, 3, 4], vec![12, 9, 15, 12]) .mode(Mode::LinesMarkers) .name("Scatter + Lines"); let layout = Layout::new().title("Adding Names to Line and Scatter Plot"); let mut plot = Plot::new(); plot.add_trace(trace1); plot.add_trace(trace2); plot.add_trace(trace3); plot.set_layout(layout); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
Line and Scatter Styling
#![allow(unused)] fn main() { fn line_and_scatter_styling(show: bool, file_name: &str) { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![10, 15, 13, 17]) .mode(Mode::Markers) .name("trace1") .marker(Marker::new().color(Rgb::new(219, 64, 82)).size(12)); let trace2 = Scatter::new(vec![2, 3, 4, 5], vec![16, 5, 11, 9]) .mode(Mode::Lines) .name("trace2") .line(Line::new().color(Rgb::new(55, 128, 191)).width(3.0)); let trace3 = Scatter::new(vec![1, 2, 3, 4], vec![12, 9, 15, 12]) .mode(Mode::LinesMarkers) .name("trace3") .marker(Marker::new().color(Rgb::new(128, 0, 128)).size(12)) .line(Line::new().color(Rgb::new(128, 0, 128)).width(1.0)); let layout = Layout::new().title("Line and Scatter Styling"); let mut plot = Plot::new(); plot.add_trace(trace1); plot.add_trace(trace2); plot.add_trace(trace3); plot.set_layout(layout); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
Styling Line Plot
#![allow(unused)] fn main() { fn styling_line_plot(show: bool, file_name: &str) { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![10, 15, 13, 17]) .mode(Mode::Markers) .name("Red") .line(Line::new().color(Rgb::new(219, 64, 82)).width(3.0)); let trace2 = Scatter::new(vec![1, 2, 3, 4], vec![12, 9, 15, 12]) .mode(Mode::LinesMarkers) .name("Blue") .line(Line::new().color(Rgb::new(55, 128, 191)).width(1.0)); let layout = Layout::new() .title("Styling Line Plot") .width(500) .height(500); let mut plot = Plot::new(); plot.add_trace(trace1); plot.add_trace(trace2); plot.set_layout(layout); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
Line Shape Options for Interpolation
#![allow(unused)] fn main() { fn line_shape_options_for_interpolation(show: bool, file_name: &str) { let trace1 = Scatter::new(vec![1, 2, 3, 4, 5], vec![1, 3, 2, 3, 1]) .mode(Mode::LinesMarkers) .name("linear") .line(Line::new().shape(LineShape::Linear)); let trace2 = Scatter::new(vec![1, 2, 3, 4, 5], vec![6, 8, 7, 8, 6]) .mode(Mode::LinesMarkers) .name("spline") .line(Line::new().shape(LineShape::Spline)); let trace3 = Scatter::new(vec![1, 2, 3, 4, 5], vec![11, 13, 12, 13, 11]) .mode(Mode::LinesMarkers) .name("vhv") .line(Line::new().shape(LineShape::Vhv)); let trace4 = Scatter::new(vec![1, 2, 3, 4, 5], vec![16, 18, 17, 18, 16]) .mode(Mode::LinesMarkers) .name("hvh") .line(Line::new().shape(LineShape::Hvh)); let trace5 = Scatter::new(vec![1, 2, 3, 4, 5], vec![21, 23, 22, 23, 21]) .mode(Mode::LinesMarkers) .name("vh") .line(Line::new().shape(LineShape::Vh)); let trace6 = Scatter::new(vec![1, 2, 3, 4, 5], vec![26, 28, 27, 28, 26]) .mode(Mode::LinesMarkers) .name("hv") .line(Line::new().shape(LineShape::Hv)); let mut plot = Plot::new(); let layout = Layout::new().legend( Legend::new() .y(0.5) .trace_order(TraceOrder::Reversed) .font(Font::new().size(16)), ); plot.set_layout(layout); plot.add_trace(trace1); plot.add_trace(trace2); plot.add_trace(trace3); plot.add_trace(trace4); plot.add_trace(trace5); plot.add_trace(trace6); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
Line Dash
#![allow(unused)] fn main() { fn line_dash(show: bool, file_name: &str) { let trace1 = Scatter::new(vec![1, 2, 3, 4, 5], vec![1, 3, 2, 3, 1]) .mode(Mode::LinesMarkers) .name("solid") .line(Line::new().dash(DashType::Solid)); let trace2 = Scatter::new(vec![1, 2, 3, 4, 5], vec![6, 8, 7, 8, 6]) .mode(Mode::LinesMarkers) .name("dashdot") .line(Line::new().dash(DashType::DashDot)); let trace3 = Scatter::new(vec![1, 2, 3, 4, 5], vec![11, 13, 12, 13, 11]) .mode(Mode::LinesMarkers) .name("dash") .line(Line::new().dash(DashType::Dash)); let trace4 = Scatter::new(vec![1, 2, 3, 4, 5], vec![16, 18, 17, 18, 16]) .mode(Mode::LinesMarkers) .name("dot") .line(Line::new().dash(DashType::Dot)); let trace5 = Scatter::new(vec![1, 2, 3, 4, 5], vec![21, 23, 22, 23, 21]) .mode(Mode::LinesMarkers) .name("longdash") .line(Line::new().dash(DashType::LongDash)); let trace6 = Scatter::new(vec![1, 2, 3, 4, 5], vec![26, 28, 27, 28, 26]) .mode(Mode::LinesMarkers) .name("longdashdot") .line(Line::new().dash(DashType::LongDashDot)); let mut plot = Plot::new(); let layout = Layout::new() .legend( Legend::new() .y(0.5) .trace_order(TraceOrder::Reversed) .font(Font::new().size(16)), ) .x_axis(Axis::new().range(vec![0.95, 5.05]).auto_range(false)) .y_axis(Axis::new().range(vec![0.0, 28.5]).auto_range(false)); plot.set_layout(layout); plot.add_trace(trace1); plot.add_trace(trace2); plot.add_trace(trace3); plot.add_trace(trace4); plot.add_trace(trace5); plot.add_trace(trace6); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
Filled Lines
#![allow(unused)] fn main() { fn filled_lines(show: bool, file_name: &str) { let x1 = vec![ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, ]; let x2 = (1..=10).map(|iv| iv as f64).collect::<Vec<f64>>(); let trace1 = Scatter::new( x1.clone(), vec![ 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0, ], ) .fill(Fill::ToZeroX) .fill_color(Rgba::new(0, 100, 80, 0.2)) .line(Line::new().color(NamedColor::Transparent)) .name("Fair") .show_legend(false); let trace2 = Scatter::new( x1.clone(), vec![ 5.5, 3.0, 5.5, 8.0, 6.0, 3.0, 8.0, 5.0, 6.0, 5.5, 4.75, 5.0, 4.0, 7.0, 2.0, 4.0, 7.0, 4.4, 2.0, 4.5, ], ) .fill(Fill::ToZeroX) .fill_color(Rgba::new(0, 176, 246, 0.2)) .line(Line::new().color(NamedColor::Transparent)) .name("Premium") .show_legend(false); let trace3 = Scatter::new( x1, vec![ 11.0, 9.0, 7.0, 5.0, 3.0, 1.0, 3.0, 5.0, 3.0, 1.0, -1.0, 1.0, 3.0, 1.0, -0.5, 1.0, 3.0, 5.0, 7.0, 9.0, ], ) .fill(Fill::ToZeroX) .fill_color(Rgba::new(231, 107, 243, 0.2)) .line(Line::new().color(NamedColor::Transparent)) .name("Fair") .show_legend(false); let trace4 = Scatter::new( x2.clone(), vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], ) .line(Line::new().color(Rgb::new(0, 100, 80))) .name("Fair"); let trace5 = Scatter::new( x2.clone(), vec![5.0, 2.5, 5.0, 7.5, 5.0, 2.5, 7.5, 4.5, 5.5, 5.0], ) .line(Line::new().color(Rgb::new(0, 176, 246))) .name("Premium"); let trace6 = Scatter::new(x2, vec![10.0, 8.0, 6.0, 4.0, 2.0, 0.0, 2.0, 4.0, 2.0, 0.0]) .line(Line::new().color(Rgb::new(231, 107, 243))) .name("Ideal"); let layout = Layout::new() .paper_background_color(Rgb::new(255, 255, 255)) .plot_background_color(Rgb::new(229, 229, 229)) .x_axis( Axis::new() .grid_color(Rgb::new(255, 255, 255)) .range(vec![1.0, 10.0]) .show_grid(true) .show_line(false) .show_tick_labels(true) .tick_color(Rgb::new(127, 127, 127)) .ticks(TicksDirection::Outside) .zero_line(false), ) .y_axis( Axis::new() .grid_color(Rgb::new(255, 255, 255)) .show_grid(true) .show_line(false) .show_tick_labels(true) .tick_color(Rgb::new(127, 127, 127)) .ticks(TicksDirection::Outside) .zero_line(false), ); let mut plot = Plot::new(); plot.set_layout(layout); plot.add_trace(trace1); plot.add_trace(trace2); plot.add_trace(trace3); plot.add_trace(trace4); plot.add_trace(trace5); plot.add_trace(trace6); let path = write_example_to_html(&plot, file_name); if show { plot.show_html(path); } } }
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.
#![allow(unused)] fn main() { 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); } } }