From d27c26162f50105f39eef4bac42b257f4e2e4784 Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 16:02:41 +0000 Subject: [PATCH 1/6] fix rendering of statistical charts --- .github/workflows/book.yml | 4 +- .../recipes/statistical_charts/box_plots.md | 461 ++---------------- .../recipes/statistical_charts/error_bars.md | 265 ++-------- .../recipes/statistical_charts/histograms.md | 330 ++----------- examples/statistical_charts/src/main.rs | 291 ++++++++--- 5 files changed, 318 insertions(+), 1033 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 284e7dc..28dfc5e 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -17,7 +17,9 @@ jobs: - uses: actions/checkout@v4 - run: cargo install mdbook - name: Build examples - run: cd ${{ github.workspace }}/examples/basic_charts && cargo run + run: | + cd ${{ github.workspace }}/examples/basic_charts && cargo run + cd ${{ github.workspace }}/examples/statistical_charts && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/recipes/statistical_charts/box_plots.md b/docs/book/src/recipes/statistical_charts/box_plots.md index 21dc5fc..25bfdde 100644 --- a/docs/book/src/recipes/statistical_charts/box_plots.md +++ b/docs/book/src/recipes/statistical_charts/box_plots.md @@ -2,8 +2,8 @@ The following imports have been used to produce the plots below: -```rust -use itertools_num::linspace; +```rust,no_run +use ndarray::Array; use plotly::box_plot::{BoxMean, BoxPoints}; use plotly::common::{ErrorData, ErrorType, Line, Marker, Mode, Orientation, Title}; use plotly::histogram::{Bins, Cumulative, HistFunc, HistNorm}; @@ -17,459 +17,64 @@ The `to_inline_html` method is used to produce the html plot displayed in this p ## Basic Box Plot -```rust -fn basic_box_plot(show: bool) { - let mut rng = rand::thread_rng(); - let uniform1 = Uniform::new(0.0, 1.0); - let uniform2 = Uniform::new(1.0, 2.0); - let n = 50; - - let mut y0 = Vec::with_capacity(n); - let mut y1 = Vec::with_capacity(n); - - for _ in 0..n { - y0.push(uniform1.sample(&mut rng)); - y1.push(uniform2.sample(&mut rng)); - } - - let trace1 = BoxPlot::::new(y0); - let trace2 = BoxPlot::::new(y1); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("basic_box_plot")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:basic_box_plot}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/basic_box_plot.html}} -## Box Plot that Displays the Underlying Data -```rust -fn box_plot_that_displays_the_underlying_data(show: bool) { - let trace1 = BoxPlot::new(vec![0, 1, 1, 2, 3, 5, 8, 13, 21]) - .box_points(BoxPoints::All) - .jitter(0.3) - .point_pos(-1.8); - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("box_plot_that_displays_the_underlying_data")) - ); -} +## Box Plot that Displays the Underlying Data +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:box_plot_that_displays_the_underlying_data}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/box_plot_that_displays_the_underlying_data.html}} -## Horizontal Box Plot -```rust -fn horizontal_box_plot(show: bool) { - let trace1 = BoxPlot::new(vec![1, 2, 3, 4, 4, 4, 8, 9, 10]).name("Set 1"); - let trace2 = BoxPlot::new(vec![2, 3, 3, 3, 3, 5, 6, 6, 7]).name("Set 2"); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("horizontal_box_plot")) - ); -} +## Horizontal Box Plot +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:horizontal_box_plot}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/horizontal_box_plot.html}} -## Grouped Box Plot -```rust -fn grouped_box_plot(show: bool) { - let x = vec![ - "day 1", "day 1", "day 1", "day 1", "day 1", "day 1", "day 2", "day 2", "day 2", "day 2", - "day 2", "day 2", - ]; - - let trace1 = BoxPlot::new_xy( - x.clone(), - vec![0.2, 0.2, 0.6, 1.0, 0.5, 0.4, 0.2, 0.7, 0.9, 0.1, 0.5, 0.3], - ); - let trace2 = BoxPlot::new_xy( - x.clone(), - vec![0.6, 0.7, 0.3, 0.6, 0.0, 0.5, 0.7, 0.9, 0.5, 0.8, 0.7, 0.2], - ); - let trace3 = BoxPlot::new_xy( - x.clone(), - vec![0.1, 0.3, 0.1, 0.9, 0.6, 0.6, 0.9, 1.0, 0.3, 0.6, 0.8, 0.5], - ); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - - let layout = Layout::new() - .y_axis( - Axis::new() - .title(Title::with_text("normalized moisture")) - .zero_line(false), - ) - .box_mode(BoxMode::Group); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("grouped_box_plot")) - ); -} +## Grouped Box Plot +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:grouped_box_plot}} ``` -
- - -## Box Plot Styling Outliers -```rust -fn box_plot_styling_outliers(show: bool) { - let y = vec![ - 0.75, 5.25, 5.5, 6.0, 6.2, 6.6, 6.80, 7.0, 7.2, 7.5, 7.5, 7.75, 8.15, 8.15, 8.65, 8.93, - 9.2, 9.5, 10.0, 10.25, 11.5, 12.0, 16.0, 20.90, 22.3, 23.25, - ]; - let trace1 = BoxPlot::new(y.clone()) - .name("All Points") - .jitter(0.3) - .point_pos(-1.8) - .marker(Marker::new().color(Rgb::new(7, 40, 89))) - .box_points(BoxPoints::All); - let trace2 = BoxPlot::new(y.clone()) - .name("Only Whiskers") - .marker(Marker::new().color(Rgb::new(9, 56, 125))) - .box_points(BoxPoints::False); - let trace3 = BoxPlot::new(y.clone()) - .name("Suspected Outlier") - .marker( - Marker::new() - .color(Rgb::new(8, 81, 156)) - .outlier_color(Rgba::new(219, 64, 82, 0.6)) - .line( - Line::new() - .outlier_color(Rgba::new(219, 64, 82, 1.0)) - .outlier_width(2), - ), - ) - .box_points(BoxPoints::SuspectedOutliers); - let trace4 = BoxPlot::new(y.clone()) - .name("Whiskers and Outliers") - .marker(Marker::new().color(Rgb::new(107, 174, 214))) - .box_points(BoxPoints::Outliers); +{{#include ../../../../../examples/statistical_charts/out/grouped_box_plot.html}} - let layout = Layout::new().title(Title::with_text("Box Plot Styling Outliers")); - 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); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("box_plot_styling_outliers")) - ); -} +## Box Plot Styling Outliers +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:box_plot_styling_outliers}} ``` -
- - -## Box Plot Styling Mean and Standard Deviation -```rust -fn box_plot_styling_mean_and_standard_deviation(show: bool) { - let y = vec![ - 2.37, 2.16, 4.82, 1.73, 1.04, 0.23, 1.32, 2.91, 0.11, 4.51, 0.51, 3.75, 1.35, 2.98, 4.50, - 0.18, 4.66, 1.30, 2.06, 1.19, - ]; +{{#include ../../../../../examples/statistical_charts/out/box_plot_styling_outliers.html}} - let trace1 = BoxPlot::new(y.clone()) - .name("Only Mean") - .marker(Marker::new().color(Rgb::new(8, 81, 156))) - .box_mean(BoxMean::True); - let trace2 = BoxPlot::new(y.clone()) - .name("Mean and Standard Deviation") - .marker(Marker::new().color(Rgb::new(8, 81, 156))) - .box_mean(BoxMean::StandardDeviation); - let layout = Layout::new().title(Title::with_text("Box Plot Styling Mean and Standard Deviation")); - let mut plot = Plot::new(); - plot.set_layout(layout); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("box_plot_styling_mean_and_standard_deviation")) - ); -} +## Box Plot Styling Mean and Standard Deviation +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:box_plot_styling_mean_and_standard_deviation}} ``` -
- - - -## Grouped Horizontal Box Plot -```rust -fn grouped_horizontal_box_plot(show: bool) { - let x = vec![ - "day 1", "day 1", "day 1", "day 1", "day 1", "day 1", "day 2", "day 2", "day 2", "day 2", - "day 2", "day 2", - ]; - let trace1 = BoxPlot::new_xy( - vec![0.2, 0.2, 0.6, 1.0, 0.5, 0.4, 0.2, 0.7, 0.9, 0.1, 0.5, 0.3], - x.clone(), - ) - .name("Kale") - .marker(Marker::new().color("3D9970")) - .box_mean(BoxMean::False) - .orientation(Orientation::Horizontal); - let trace2 = BoxPlot::new_xy( - vec![0.6, 0.7, 0.3, 0.6, 0.0, 0.5, 0.7, 0.9, 0.5, 0.8, 0.7, 0.2], - x.clone(), - ) - .name("Radishes") - .marker(Marker::new().color("FF4136")) - .box_mean(BoxMean::False) - .orientation(Orientation::Horizontal); - let trace3 = BoxPlot::new_xy( - vec![0.1, 0.3, 0.1, 0.9, 0.6, 0.6, 0.9, 1.0, 0.3, 0.6, 0.8, 0.5], - x.clone(), - ) - .name("Carrots") - .marker(Marker::new().color("FF851B")) - .box_mean(BoxMean::False) - .orientation(Orientation::Horizontal); +{{#include ../../../../../examples/statistical_charts/out/box_plot_styling_mean_and_standard_deviation.html}} - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - let layout = Layout::new() - .title(Title::with_text("Grouped Horizontal Box Plot")) - .x_axis( - Axis::new() - .title(Title::with_text("normalized moisture")) - .zero_line(false), - ) - .box_mode(BoxMode::Group); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("grouped_horizontal_box_plot")) - ); -} +## Grouped Horizontal Box Plot +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:grouped_horizontal_box_plot}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/grouped_horizontal_box_plot.html}} ## Fully Styled Box Plot -```rust -fn fully_styled_box_plot(show: bool) { - let rnd_sample = |num, mul| -> Vec { - let mut v: Vec = Vec::with_capacity(num); - let mut rng = rand::thread_rng(); - let uniform = Uniform::new(0.0, mul); - for _ in 0..num { - v.push(uniform.sample(&mut rng)); - } - v - }; - - let x_data = vec![ - "Carmelo
Anthony", - "Dwyane
Wade", - "Deron
Williams", - "Brook
Lopez", - "Damian
Lillard", - "David
West", - "Blake
Griffin", - "David
Lee", - "Demar
Derozan", - ]; - let y_data = vec![ - rnd_sample(30, 10.0), - rnd_sample(30, 20.0), - rnd_sample(30, 25.0), - rnd_sample(30, 40.0), - rnd_sample(30, 45.0), - rnd_sample(30, 30.0), - rnd_sample(30, 20.0), - rnd_sample(30, 15.0), - rnd_sample(30, 43.0), - ]; - - let mut plot = Plot::new(); - let layout = Layout::new() - .title(Title::new( - "Points Scored by the Top 9 Scoring NBA Players in 2012", - )) - .y_axis( - Axis::new() - .auto_range(true) - .show_grid(true) - .zero_line(true) - .dtick(5.0) - .grid_color(Rgb::new(255, 255, 255)) - .grid_width(1) - .zero_line_color(Rgb::new(255, 255, 255)) - .zero_line_width(2), - ) - .margin(Margin::new().left(40).right(30).bottom(80).top(100)) - .paper_background_color(Rgb::new(243, 243, 243)) - .plot_background_color(Rgb::new(243, 243, 243)) - .show_legend(false); - plot.set_layout(layout); - - for index in 0..x_data.len() { - let trace = BoxPlot::new(y_data[index].clone()) - .name(x_data[index]) - .box_points(BoxPoints::All) - .jitter(0.5) - .whisker_width(0.2) - .marker(Marker::new().size(6)) - .line(Line::new().width(2.0)); - plot.add_trace(trace); - } - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("fully_styled_box_plot")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:fully_styled_box_plot}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/statistical_charts/out/fully_styled_box_plot.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/statistical_charts/error_bars.md b/docs/book/src/recipes/statistical_charts/error_bars.md index 43b47e6..9602401 100644 --- a/docs/book/src/recipes/statistical_charts/error_bars.md +++ b/docs/book/src/recipes/statistical_charts/error_bars.md @@ -2,8 +2,8 @@ The following imports have been used to produce the plots below: -```rust -use itertools_num::linspace; +```rust,no_run +use ndarray::Array; use plotly::box_plot::{BoxMean, BoxPoints}; use plotly::common::{ErrorData, ErrorType, Line, Marker, Mode, Orientation, Title}; use plotly::histogram::{Bins, Cumulative, HistFunc, HistNorm}; @@ -16,263 +16,54 @@ use rand_distr::{Distribution, Normal, Uniform}; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Basic Symmetric Error Bars -```rust -fn basic_symmetric_error_bars(show: bool) { - let trace1 = Scatter::new(vec![0, 1, 2], vec![6, 10, 2]) - .name("trace1") - .error_y(ErrorData::new(ErrorType::Data).array(vec![1.0, 2.0, 3.0])); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("basic_symmetric_error_bars")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:basic_symmetric_error_bars}} ``` -
- -## Asymmetric Error Bars -```rust -fn asymmetric_error_bars(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) - .name("trace1") - .error_y( - ErrorData::new(ErrorType::Data) - .array(vec![0.1, 0.2, 0.1, 0.1]) - .array_minus(vec![0.2, 0.4, 1., 0.2]), - ); +{{#include ../../../../../examples/statistical_charts/out/basic_symmetric_error_bars.html}} - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("asymmetric_error_bars"))); -} +## Asymmetric Error Bars +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:asymmetric_error_bars}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/asymmetric_error_bars.html}} ## Error Bars as a Percentage of the Y Value -```rust -fn error_bars_as_a_percentage_of_the_y_value(show: bool) { - let trace1 = Scatter::new(vec![0, 1, 2], vec![6, 10, 2]) - .name("trace1") - .error_y(ErrorData::new(ErrorType::Percent).value(50.).visible(true)); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("error_bars_as_a_percentage_of_the_y_value")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:error_bars_as_a_percentage_of_the_y_value}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/error_bars_as_a_percentage_of_the_y_value.html}} -## Asymmetric Error Bars with a Constant Offset -```rust -fn asymmetric_error_bars_with_a_constant_offset(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) - .name("trace1") - .error_y( - ErrorData::new(ErrorType::Percent) - .symmetric(false) - .value(15.) - .value_minus(25.), - ); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("asymmetric_error_bars_with_a_constant_offset")) - ); -} +## Asymmetric Error Bars with a Constant Offset +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:asymmetric_error_bars_with_a_constant_offset}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/asymmetric_error_bars_with_a_constant_offset.html}} -## Horizontal Error Bars -```rust -fn horizontal_error_bars(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) - .name("trace1") - .error_x(ErrorData::new(ErrorType::Percent).value(10.)); - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("horizontal_error_bars"))); -} +## Horizontal Error Bars +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:horizontal_error_bars}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/horizontal_error_bars.html}} -## Bar Chart with Error Bars -```rust -fn bar_chart_with_error_bars(show: bool) { - let trace_c = Bar::new(vec!["Trial 1", "Trial 2", "Trial 3"], vec![3, 6, 4]) - .error_y(ErrorData::new(ErrorType::Data).array(vec![1., 0.5, 1.5])); - let trace_e = Bar::new(vec!["Trial 1", "Trial 2", "Trial 3"], vec![4, 7, 3]) - .error_y(ErrorData::new(ErrorType::Data).array(vec![0.5, 1., 2.])); - - let mut plot = Plot::new(); - plot.add_trace(trace_c); - plot.add_trace(trace_e); - let layout = Layout::new().bar_mode(BarMode::Group); - plot.set_layout(layout); - - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("bar_chart_with_error_bars"))); -} +## Bar Chart with Error Bars +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:bar_chart_with_error_bars}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/bar_chart_with_error_bars.html}} -## Colored and Styled Error Bars -```rust -fn colored_and_styled_error_bars(show: bool) { - let x_theo: Vec = linspace(-4., 4., 100).collect(); - let sincx: Vec = x_theo - .iter() - .map(|x| (x * std::f64::consts::PI).sin() / (*x * std::f64::consts::PI)) - .collect(); - let x = vec![ - -3.8, -3.03, -1.91, -1.46, -0.89, -0.24, -0.0, 0.41, 0.89, 1.01, 1.91, 2.28, 2.79, 3.56, - ]; - let y = vec![ - -0.02, 0.04, -0.01, -0.27, 0.36, 0.75, 1.03, 0.65, 0.28, 0.02, -0.11, 0.16, 0.04, -0.15, - ]; - - let trace1 = Scatter::new(x_theo, sincx).name("sinc(x)"); - let trace2 = Scatter::new(x, y) - .mode(Mode::Markers) - .name("measured") - .error_y( - ErrorData::new(ErrorType::Constant) - .value(0.1) - .color(NamedColor::Purple) - .thickness(1.5) - .width(3), - ) - .error_x( - ErrorData::new(ErrorType::Constant) - .value(0.2) - .color(NamedColor::Purple) - .thickness(1.5) - .width(3), - ) - .marker(Marker::new().color(NamedColor::Purple).size(8)); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("colored_and_styled_error_bars")) - ); -} +## Colored and Styled Error Bars +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:colored_and_styled_error_bars}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/colored_and_styled_error_bars.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/statistical_charts/histograms.md b/docs/book/src/recipes/statistical_charts/histograms.md index b2b7b8a..02e8785 100644 --- a/docs/book/src/recipes/statistical_charts/histograms.md +++ b/docs/book/src/recipes/statistical_charts/histograms.md @@ -2,8 +2,8 @@ The following imports have been used to produce the plots below: -```rust -use itertools_num::linspace; +```rust,no_run +use ndarray::Array; use plotly::box_plot::{BoxMean, BoxPoints}; use plotly::common::{ErrorData, ErrorType, Line, Marker, Mode, Orientation, Title}; use plotly::histogram::{Bins, Cumulative, HistFunc, HistNorm}; @@ -17,327 +17,63 @@ The `to_inline_html` method is used to produce the html plot displayed in this p ## Basic Histogram -```rust -fn basic_histogram(show: bool) { - let samples = sample_normal_distribution(10_000, 0.0, 1.0); - let trace = Histogram::new(samples).name("h"); - let mut plot = Plot::new(); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("basic_histogram")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:basic_histogram}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/basic_histogram.html}} -## Horizontal Histogram -```rust -fn horizontal_histogram(show: bool) { - let samples = sample_normal_distribution(10_000, 0.0, 1.0); - let trace = Histogram::new_horizontal(samples) - .name("h") - .marker(Marker::new().color(NamedColor::Pink)); - let mut plot = Plot::new(); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("horizontal_histogram")) - ); -} +## Horizontal Histogram +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:horizontal_histogram}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/horizontal_histogram.html}} ## Overlaid Histogram -```rust -fn overlaid_histogram(show: bool) { - let samples1 = sample_normal_distribution(500, 0.0, 1.0); - let trace1 = Histogram::new(samples1) - .name("trace 1") - .opacity(0.5) - .marker(Marker::new().color(NamedColor::Green)); - - let samples2 = sample_normal_distribution(500, 0.0, 1.0); - let trace2 = Histogram::new(samples2) - .name("trace 2") - .opacity(0.6) - .marker(Marker::new().color(NamedColor::Red)); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - - let layout = Layout::new().bar_mode(BarMode::Overlay); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("overlaid_histogram")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:overlaid_histogram}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/overlaid_histogram.html}} -## Stacked Histograms -```rust -fn stacked_histograms(show: bool) { - let samples1 = sample_normal_distribution(500, 0.0, 1.0); - let trace1 = Histogram::new(samples1) - .name("trace 1") - .opacity(0.5) - .marker(Marker::new().color(NamedColor::Green)); - - let samples2 = sample_normal_distribution(500, 0.0, 1.0); - let trace2 = Histogram::new(samples2) - .name("trace 2") - .opacity(0.6) - .marker(Marker::new().color(NamedColor::Red)); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - let layout = Layout::new().bar_mode(BarMode::Stack); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("stacked_histograms")) - ); -} +## Stacked Histograms +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:stacked_histograms}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/stacked_histograms.html}} -## Colored and Styled Histograms -```rust -fn colored_and_styled_histograms(show: bool) { - let n = 500; - let x1 = sample_uniform_distribution(n, 0.0, 5.0); - let x2 = sample_uniform_distribution(n, 0.0, 10.0); - let y1 = sample_uniform_distribution(n, 0.0, 1.0); - let y2 = sample_uniform_distribution(n, 0.0, 2.0); - let trace1 = Histogram::new_xy(x1, y1) - .name("control") - .hist_func(HistFunc::Count) - .marker( - Marker::new() - .color(Rgba::new(255, 100, 102, 0.7)) - .line(Line::new().color(Rgba::new(255, 100, 102, 1.0)).width(1.0)), - ) - .opacity(0.5) - .auto_bin_x(false) - .x_bins(Bins::new(0.5, 2.8, 0.06)); - let trace2 = Histogram::new_xy(x2, y2) - .name("experimental") - .hist_func(HistFunc::Count) - .marker( - Marker::new() - .color(Rgba::new(100, 200, 102, 0.7)) - .line(Line::new().color(Rgba::new(100, 200, 102, 1.0)).width(1.0)), - ) - .opacity(0.75) - .auto_bin_x(false) - .x_bins(Bins::new(-3.2, 4.0, 0.06)); - let layout = Layout::new() - .title(Title::with_text("Sampled Results")) - .x_axis(Axis::new().title(Title::with_text("Value"))) - .y_axis(Axis::new().title(Title::with_text("Count"))) - .bar_mode(BarMode::Overlay) - .bar_gap(0.05) - .bar_group_gap(0.2); - - let mut plot = Plot::new(); - plot.set_layout(layout); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("colored_and_styled_histograms")) - ); -} +## Colored and Styled Histograms +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:colored_and_styled_histograms}} ``` -
- + +{{#include ../../../../../examples/statistical_charts/out/colored_and_styled_histograms.html}} ## Cumulative Histogram -```rust -fn cumulative_histogram(show: bool) { - let n = 500; - let x = sample_uniform_distribution(n, 0.0, 1.0); - let trace = Histogram::new(x) - .cumulative(Cumulative::new().enabled(true)) - .marker(Marker::new().color(NamedColor::BurlyWood)); - let mut plot = Plot::new(); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("cumulative_histogram")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:cumulative_histogram}} ``` -
- + +{{#include ../../../../../examples/statistical_charts/out/cumulative_histogram.html}} ## Normalized Histogram -```rust -fn normalized_histogram(show: bool) { - let n = 500; - let x = sample_uniform_distribution(n, 0.0, 1.0); - let trace = Histogram::new(x) - .hist_norm(HistNorm::Probability) - .marker(Marker::new().color(NamedColor::SeaGreen)); - let mut plot = Plot::new(); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("normalized_histogram")) - ); -} +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:normalized_histogram}} ``` -
- +{{#include ../../../../../examples/statistical_charts/out/normalized_histogram.html}} -## Specify Binning Function -```rust -fn specify_binning_function(show: bool) { - let x = vec!["Apples", "Apples", "Apples", "Organges", "Bananas"]; - let y = vec!["5", "10", "3", "10", "5"]; - - let trace1 = Histogram::new_xy(x.clone(), y.clone()) - .name("count") - .hist_func(HistFunc::Count); - let trace2 = Histogram::new_xy(x.clone(), y.clone()) - .name("sum") - .hist_func(HistFunc::Sum); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("specify_binning_function")) - ); -} +## Specify Binning Function +```rust,no_run +{{#include ../../../../../examples/statistical_charts/src/main.rs:specify_binning_function}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/statistical_charts/out/specify_binning_function.html}} \ No newline at end of file diff --git a/examples/statistical_charts/src/main.rs b/examples/statistical_charts/src/main.rs index 8bde9c9..923756f 100644 --- a/examples/statistical_charts/src/main.rs +++ b/examples/statistical_charts/src/main.rs @@ -12,7 +12,8 @@ use plotly::{ use rand_distr::{Distribution, Normal, Uniform}; // Error Bars -fn basic_symmetric_error_bars() { +// ANCHOR: basic_symmetric_error_bars +fn basic_symmetric_error_bars(show: bool) -> Plot { let trace1 = Scatter::new(vec![0, 1, 2], vec![6, 10, 2]) .name("trace1") .error_y(ErrorData::new(ErrorType::Data).array(vec![1.0, 2.0, 3.0])); @@ -20,10 +21,15 @@ fn basic_symmetric_error_bars() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: basic_symmetric_error_bars -fn asymmetric_error_bars() { +// ANCHOR: asymmetric_error_bars +fn asymmetric_error_bars(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) .name("trace1") .error_y( @@ -35,10 +41,15 @@ fn asymmetric_error_bars() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: asymmetric_error_bars -fn error_bars_as_a_percentage_of_the_y_value() { +// ANCHOR: error_bars_as_a_percentage_of_the_y_value +fn error_bars_as_a_percentage_of_the_y_value(show: bool) -> Plot { let trace1 = Scatter::new(vec![0, 1, 2], vec![6, 10, 2]) .name("trace1") .error_y(ErrorData::new(ErrorType::Percent).value(50.).visible(true)); @@ -46,10 +57,15 @@ fn error_bars_as_a_percentage_of_the_y_value() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: error_bars_as_a_percentage_of_the_y_value -fn asymmetric_error_bars_with_a_constant_offset() { +// ANCHOR: asymmetric_error_bars_with_a_constant_offset +fn asymmetric_error_bars_with_a_constant_offset(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) .name("trace1") .error_y( @@ -62,10 +78,15 @@ fn asymmetric_error_bars_with_a_constant_offset() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: asymmetric_error_bars_with_a_constant_offset -fn horizontal_error_bars() { +// ANCHOR: horizontal_error_bars +fn horizontal_error_bars(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3, 4], vec![2, 1, 3, 4]) .name("trace1") .error_x(ErrorData::new(ErrorType::Percent).value(10.)); @@ -73,10 +94,15 @@ fn horizontal_error_bars() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: horizontal_error_bars -fn bar_chart_with_error_bars() { +// ANCHOR: bar_chart_with_error_bars +fn bar_chart_with_error_bars(show: bool) -> Plot { let trace_c = Bar::new(vec!["Trial 1", "Trial 2", "Trial 3"], vec![3, 6, 4]) .error_y(ErrorData::new(ErrorType::Data).array(vec![1., 0.5, 1.5])); let trace_e = Bar::new(vec!["Trial 1", "Trial 2", "Trial 3"], vec![4, 7, 3]) @@ -89,10 +115,15 @@ fn bar_chart_with_error_bars() { let layout = Layout::new().bar_mode(BarMode::Group); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: bar_chart_with_error_bars -fn colored_and_styled_error_bars() { +// ANCHOR: colored_and_styled_error_bars +fn colored_and_styled_error_bars(show: bool) -> Plot { let x_theo: Vec = Array::linspace(-4., 4., 100).into_raw_vec_and_offset().0; let sincx: Vec = x_theo .iter() @@ -129,11 +160,16 @@ fn colored_and_styled_error_bars() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: colored_and_styled_error_bars // Box Plots -fn basic_box_plot() { +// ANCHOR: basic_box_plot +fn basic_box_plot(show: bool) -> Plot { let mut rng = rand::thread_rng(); let uniform1 = Uniform::new(0.0, 1.0); let uniform2 = Uniform::new(1.0, 2.0); @@ -153,10 +189,15 @@ fn basic_box_plot() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: basic_box_plot -fn box_plot_that_displays_the_underlying_data() { +// ANCHOR: box_plot_that_displays_the_underlying_data +fn box_plot_that_displays_the_underlying_data(show: bool) -> Plot { let trace1 = BoxPlot::new(vec![0, 1, 1, 2, 3, 5, 8, 13, 21]) .box_points(BoxPoints::All) .jitter(0.3) @@ -164,10 +205,15 @@ fn box_plot_that_displays_the_underlying_data() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: box_plot_that_displays_the_underlying_data -fn horizontal_box_plot() { +// ANCHOR: horizontal_box_plot +fn horizontal_box_plot(show: bool) -> Plot { let trace1 = BoxPlot::new(vec![1, 2, 3, 4, 4, 4, 8, 9, 10]).name("Set 1"); let trace2 = BoxPlot::new(vec![2, 3, 3, 3, 3, 5, 6, 6, 7]).name("Set 2"); @@ -175,10 +221,15 @@ fn horizontal_box_plot() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: horizontal_box_plot -fn grouped_box_plot() { +// ANCHOR: grouped_box_plot +fn grouped_box_plot(show: bool) -> Plot { let x = vec![ "day 1", "day 1", "day 1", "day 1", "day 1", "day 1", "day 2", "day 2", "day 2", "day 2", "day 2", "day 2", @@ -208,10 +259,15 @@ fn grouped_box_plot() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: grouped_box_plot -fn box_plot_styling_outliers() { +// ANCHOR: box_plot_styling_outliers +fn box_plot_styling_outliers(show: bool) -> Plot { let y = vec![ 0.75, 5.25, 5.5, 6.0, 6.2, 6.6, 6.80, 7.0, 7.2, 7.5, 7.5, 7.75, 8.15, 8.15, 8.65, 8.93, 9.2, 9.5, 10.0, 10.25, 11.5, 12.0, 16.0, 20.90, 22.3, 23.25, @@ -253,10 +309,15 @@ fn box_plot_styling_outliers() { plot.add_trace(trace3); plot.add_trace(trace4); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: box_plot_styling_outliers -fn box_plot_styling_mean_and_standard_deviation() { +// ANCHOR: box_plot_styling_mean_and_standard_deviation +fn box_plot_styling_mean_and_standard_deviation(show: bool) -> Plot { let y = vec![ 2.37, 2.16, 4.82, 1.73, 1.04, 0.23, 1.32, 2.91, 0.11, 4.51, 0.51, 3.75, 1.35, 2.98, 4.50, 0.18, 4.66, 1.30, 2.06, 1.19, @@ -277,10 +338,15 @@ fn box_plot_styling_mean_and_standard_deviation() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: box_plot_styling_mean_and_standard_deviation -fn grouped_horizontal_box_plot() { +// ANCHOR: grouped_horizontal_box_plot +fn grouped_horizontal_box_plot(show: bool) -> Plot { let x = vec![ "day 1", "day 1", "day 1", "day 1", "day 1", "day 1", "day 2", "day 2", "day 2", "day 2", "day 2", "day 2", @@ -323,10 +389,15 @@ fn grouped_horizontal_box_plot() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: grouped_horizontal_box_plot -fn fully_styled_box_plot() { +// ANCHOR: fully_styled_box_plot +fn fully_styled_box_plot(show: bool) -> Plot { let rnd_sample = |num, mul| -> Vec { let mut v: Vec = Vec::with_capacity(num); let mut rng = rand::thread_rng(); @@ -391,8 +462,12 @@ fn fully_styled_box_plot() { plot.add_trace(trace); } - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: fully_styled_box_plot // Histograms fn sample_normal_distribution(n: usize, mean: f64, std_dev: f64) -> Vec { @@ -415,16 +490,22 @@ fn sample_uniform_distribution(n: usize, lb: f64, ub: f64) -> Vec { v } -fn basic_histogram() { +// ANCHOR: basic_histogram +fn basic_histogram(show: bool) -> Plot { let samples = sample_normal_distribution(10_000, 0.0, 1.0); let trace = Histogram::new(samples).name("h"); let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: basic_histogram -fn horizontal_histogram() { +// ANCHOR: horizontal_histogram +fn horizontal_histogram(show: bool) -> Plot { let samples = sample_normal_distribution(10_000, 0.0, 1.0); let trace = Histogram::new_vertical(samples) .name("h") @@ -433,10 +514,15 @@ fn horizontal_histogram() { plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: horizontal_histogram -fn overlaid_histogram() { +// ANCHOR: overlaid_histogram +fn overlaid_histogram(show: bool) -> Plot { let samples1 = sample_normal_distribution(500, 0.0, 1.0); let trace1 = Histogram::new(samples1) .name("trace 1") @@ -456,10 +542,15 @@ fn overlaid_histogram() { let layout = Layout::new().bar_mode(BarMode::Overlay); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: overlaid_histogram -fn stacked_histograms() { +// ANCHOR: stacked_histograms +fn stacked_histograms(show: bool) -> Plot { let samples1 = sample_normal_distribution(500, 0.0, 1.0); let trace1 = Histogram::new(samples1) .name("trace 1") @@ -479,10 +570,15 @@ fn stacked_histograms() { let layout = Layout::new().bar_mode(BarMode::Stack); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: stacked_histograms -fn colored_and_styled_histograms() { +// ANCHOR: colored_and_styled_histograms +fn colored_and_styled_histograms(show: bool) -> Plot { let n = 500; let x1 = sample_uniform_distribution(n, 0.0, 5.0); let x2 = sample_uniform_distribution(n, 0.0, 10.0); @@ -524,10 +620,15 @@ fn colored_and_styled_histograms() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: colored_and_styled_histograms -fn cumulative_histogram() { +// ANCHOR: cumulative_histogram +fn cumulative_histogram(show: bool) -> Plot { let n = 500; let x = sample_uniform_distribution(n, 0.0, 1.0); let trace = Histogram::new(x) @@ -536,10 +637,15 @@ fn cumulative_histogram() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: cumulative_histogram -fn normalized_histogram() { +// ANCHOR: normalized_histogram +fn normalized_histogram(show: bool) -> Plot { let n = 500; let x = sample_uniform_distribution(n, 0.0, 1.0); let trace = Histogram::new(x) @@ -548,10 +654,15 @@ fn normalized_histogram() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: normalized_histogram -fn specify_binning_function() { +// ANCHOR: specify_binning_function +fn specify_binning_function(show: bool) -> Plot { let x = vec!["Apples", "Apples", "Apples", "Oranges", "Bananas"]; let y = vec!["5", "10", "3", "10", "5"]; @@ -566,38 +677,78 @@ fn specify_binning_function() { plot.add_trace(trace1); plot.add_trace(trace2); - plot.show(); + if show { + plot.show(); + } + plot +} +// ANCHOR_END: specify_binning_function + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. + // Change false to true on any of these lines to display the example. // Error Bars - // basic_symmetric_error_bars(); - // asymmetric_error_bars(); - // error_bars_as_a_percentage_of_the_y_value(); - // asymmetric_error_bars_with_a_constant_offset(); - // horizontal_error_bars(); - // bar_chart_with_error_bars(); - // colored_and_styled_error_bars(); + write_example_to_html( + basic_symmetric_error_bars(false), + "basic_symmetric_error_bars", + ); + write_example_to_html(asymmetric_error_bars(false), "asymmetric_error_bars"); + write_example_to_html( + error_bars_as_a_percentage_of_the_y_value(false), + "error_bars_as_a_percentage_of_the_y_value", + ); + write_example_to_html( + asymmetric_error_bars_with_a_constant_offset(false), + "asymmetric_error_bars_with_a_constant_offset", + ); + write_example_to_html(horizontal_error_bars(false), "horizontal_error_bars"); + write_example_to_html( + bar_chart_with_error_bars(false), + "bar_chart_with_error_bars", + ); + write_example_to_html( + colored_and_styled_error_bars(false), + "colored_and_styled_error_bars", + ); // Box Plots - // basic_box_plot(); - // box_plot_that_displays_the_underlying_data(); - // horizontal_box_plot(); - // grouped_box_plot(); - // box_plot_styling_outliers(); - // box_plot_styling_mean_and_standard_deviation(); - // grouped_horizontal_box_plot(); - // fully_styled_box_plot(); + write_example_to_html(basic_box_plot(false), "basic_box_plot"); + write_example_to_html( + box_plot_that_displays_the_underlying_data(false), + "box_plot_that_displays_the_underlying_data", + ); + write_example_to_html(horizontal_box_plot(false), "horizontal_box_plot"); + write_example_to_html(grouped_box_plot(false), "grouped_box_plot"); + write_example_to_html( + box_plot_styling_outliers(false), + "box_plot_styling_outliers", + ); + write_example_to_html( + box_plot_styling_mean_and_standard_deviation(false), + "box_plot_styling_mean_and_standard_deviation", + ); + write_example_to_html( + grouped_horizontal_box_plot(false), + "grouped_horizontal_box_plot", + ); + write_example_to_html(fully_styled_box_plot(false), "fully_styled_box_plot"); // Histograms - // basic_histogram(); - // horizontal_histogram(); - // overlaid_histogram(); - // stacked_histograms(); - // colored_and_styled_histograms(); - // cumulative_histogram(); - // normalized_histogram(); - // specify_binning_function(); + write_example_to_html(basic_histogram(false), "basic_histogram"); + write_example_to_html(horizontal_histogram(false), "horizontal_histogram"); + write_example_to_html(overlaid_histogram(false), "overlaid_histogram"); + write_example_to_html(stacked_histograms(false), "stacked_histograms"); + write_example_to_html( + colored_and_styled_histograms(false), + "colored_and_styled_histograms", + ); + write_example_to_html(cumulative_histogram(false), "cumulative_histogram"); + write_example_to_html(normalized_histogram(false), "normalized_histogram"); + write_example_to_html(specify_binning_function(false), "specify_binning_function"); } From e228676d499b522fc1f1d2d957647ec3b2f3717f Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 16:53:54 +0000 Subject: [PATCH 2/6] fix rendering of scientific charts --- .github/workflows/book.yml | 1 + .../scientific_charts/contour_plots.md | 179 ++---------------- .../src/recipes/scientific_charts/heatmaps.md | 29 +-- examples/scientific_charts/src/main.rs | 83 ++++++-- 4 files changed, 87 insertions(+), 205 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 28dfc5e..7fd130f 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -20,6 +20,7 @@ jobs: run: | cd ${{ github.workspace }}/examples/basic_charts && cargo run cd ${{ github.workspace }}/examples/statistical_charts && cargo run + cd ${{ github.workspace }}/examples/scientific_charts && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/recipes/scientific_charts/contour_plots.md b/docs/book/src/recipes/scientific_charts/contour_plots.md index 6ce5c80..0f878d2 100644 --- a/docs/book/src/recipes/scientific_charts/contour_plots.md +++ b/docs/book/src/recipes/scientific_charts/contour_plots.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{ColorScale, ColorScalePalette, Title}; use plotly::contour::Contours; use plotly::{Contour, HeatMap, Layout, Plot}; @@ -12,177 +12,32 @@ use std::f64::consts::PI; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Simple Contour Plot -```rust -fn simple_contour_plot(show: bool) { - let n = 200; - let mut x = Vec::::new(); - let mut y = Vec::::new(); - let mut z: Vec> = Vec::new(); - - for index in 0..n { - let value = -2.0 * PI + 4.0 * PI * (index as f64) / (n as f64); - x.push(value); - y.push(value); - } - - for xi in 0..n { - let mut row = Vec::::new(); - for yi in 0..n { - let radius_squared = x[xi].powf(2.0) + y[yi].powf(2.0); - let zv = - x[xi].sin() * y[yi].cos() * radius_squared.sin() / (radius_squared + 1.0).log10(); - row.push(zv); - } - z.push(row); - } - - let trace = Contour::new(x, y, z); - let mut plot = Plot::new(); - - plot.add_trace(trace); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("simple_contour_plot"))); -} +```rust,no_run +{{#include ../../../../../examples/scientific_charts/src/main.rs:simple_contour_plot}} ``` -
- - -## Colorscale for Contour Plot -```rust -fn colorscale_for_contour_plot(show: bool) { - let z = vec![ - vec![10.0, 10.625, 12.5, 15.625, 20.0], - vec![5.625, 6.25, 8.125, 11.25, 15.625], - vec![2.5, 3.125, 5., 8.125, 12.5], - vec![0.625, 1.25, 3.125, 6.25, 10.625], - vec![0.0, 0.625, 2.5, 5.625, 10.0], - ]; - let trace = Contour::new_z(z).color_scale(ColorScale::Palette(ColorScalePalette::Jet)); +{{#include ../../../../../examples/scientific_charts/out/simple_contour_plot.html}} - let layout = Layout::new().title(Title::with_text("Colorscale for Contour Plot")); - let mut plot = Plot::new(); - plot.set_layout(layout); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("colorscale_for_contour_plot")) - ); -} +## Colorscale for Contour Plot +```rust,no_run +{{#include ../../../../../examples/scientific_charts/src/main.rs:colorscale_for_contour_plot}} ``` -
- +{{#include ../../../../../examples/scientific_charts/out/colorscale_for_contour_plot.html}} -## Customizing Size and Range of a Contour Plot Contours -```rust -fn customizing_size_and_range_of_a_contour_plots_contours(show: bool) { - let z = vec![ - vec![10.0, 10.625, 12.5, 15.625, 20.0], - vec![5.625, 6.25, 8.125, 11.25, 15.625], - vec![2.5, 3.125, 5., 8.125, 12.5], - vec![0.625, 1.25, 3.125, 6.25, 10.625], - vec![0.0, 0.625, 2.5, 5.625, 10.0], - ]; - let trace = Contour::new_z(z) - .color_scale(ColorScale::Palette(ColorScalePalette::Jet)) - .auto_contour(false) - .contours(Contours::new().start(0.0).end(8.0).size(2.0)); - let layout = Layout::new().title(Title::with_text("Customizing Size and Range of Contours")); - let mut plot = Plot::new(); - plot.set_layout(layout); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "customizing_size_and_range_of_a_contour_plots_contours" - )) - ); -} +## Customizing Size and Range of a Contour Plot Contours +```rust,no_run +{{#include ../../../../../examples/scientific_charts/src/main.rs:customizing_size_and_range_of_a_contour_plots_contours}} ``` -
- +{{#include ../../../../../examples/scientific_charts/out/customizing_size_and_range_of_a_contour_plots_contours.html}} -## Customizing Spacing Between X and Y Ticks -```rust -fn customizing_spacing_between_x_and_y_ticks(show: bool) { - let z = vec![ - vec![10.0, 10.625, 12.5, 15.625, 20.0], - vec![5.625, 6.25, 8.125, 11.25, 15.625], - vec![2.5, 3.125, 5., 8.125, 12.5], - vec![0.625, 1.25, 3.125, 6.25, 10.625], - vec![0.0, 0.625, 2.5, 5.625, 10.0], - ]; - let trace = Contour::new_z(z) - .color_scale(ColorScale::Palette(ColorScalePalette::Jet)) - .dx(10.0) - .x0(5.0) - .dy(10.0) - .y0(10.0); - let layout = Layout::new().title(Title::with_text("Customizing Size and Range of Contours")); - let mut plot = Plot::new(); - plot.set_layout(layout); - plot.add_trace(trace); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("customizing_spacing_between_x_and_y_ticks")) - ); -} +## Customizing Spacing Between X and Y Ticks +```rust,no_run +{{#include ../../../../../examples/scientific_charts/src/main.rs:customizing_spacing_between_x_and_y_ticks}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/scientific_charts/out/customizing_spacing_between_x_and_y_ticks.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/scientific_charts/heatmaps.md b/docs/book/src/recipes/scientific_charts/heatmaps.md index 64c78cd..00d3ef8 100644 --- a/docs/book/src/recipes/scientific_charts/heatmaps.md +++ b/docs/book/src/recipes/scientific_charts/heatmaps.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{ColorScale, ColorScalePalette, Title}; use plotly::contour::Contours; use plotly::{Contour, HeatMap, Layout, Plot}; @@ -12,27 +12,8 @@ use std::f64::consts::PI; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Basic Heatmap -```rust -fn basic_heat_map(show: bool) { - let z = vec![vec![1, 20, 30], vec![20, 1, 60], vec![30, 60, 1]]; - let trace = HeatMap::new_z(z); - let mut plot = Plot::new(); - plot.add_trace(trace); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("basic_heat_map"))); -} +```rust,no_run +{{#include ../../../../../examples/scientific_charts/src/main.rs:basic_heat_map}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/scientific_charts/out/basic_heat_map.html}} \ No newline at end of file diff --git a/examples/scientific_charts/src/main.rs b/examples/scientific_charts/src/main.rs index ff0d85d..85d06d4 100644 --- a/examples/scientific_charts/src/main.rs +++ b/examples/scientific_charts/src/main.rs @@ -7,7 +7,8 @@ use plotly::contour::Contours; use plotly::{Contour, HeatMap, Layout, Plot}; // Contour Plots -fn simple_contour_plot() { +// ANCHOR: simple_contour_plot +fn simple_contour_plot(show: bool) -> Plot { let n = 200; let mut x = Vec::::new(); let mut y = Vec::::new(); @@ -34,10 +35,15 @@ fn simple_contour_plot() { plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_contour_plot -fn colorscale_for_contour_plot() { +// ANCHOR: colorscale_for_contour_plot +fn colorscale_for_contour_plot(show: bool) -> Plot { let z = vec![ vec![10.0, 10.625, 12.5, 15.625, 20.0], vec![5.625, 6.25, 8.125, 11.25, 15.625], @@ -52,10 +58,15 @@ fn colorscale_for_contour_plot() { plot.set_layout(layout); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: colorscale_for_contour_plot -fn customizing_size_and_range_of_a_contour_plots_contours() { +// ANCHOR: customizing_size_and_range_of_a_contour_plots_contours +fn customizing_size_and_range_of_a_contour_plots_contours(show: bool) -> Plot { let z = vec![ vec![10.0, 10.625, 12.5, 15.625, 20.0], vec![5.625, 6.25, 8.125, 11.25, 15.625], @@ -73,10 +84,15 @@ fn customizing_size_and_range_of_a_contour_plots_contours() { plot.set_layout(layout); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: customizing_size_and_range_of_a_contour_plots_contours -fn customizing_spacing_between_x_and_y_ticks() { +// ANCHOR: customizing_spacing_between_x_and_y_ticks +fn customizing_spacing_between_x_and_y_ticks(show: bool) -> Plot { let z = vec![ vec![10.0, 10.625, 12.5, 15.625, 20.0], vec![5.625, 6.25, 8.125, 11.25, 15.625], @@ -96,20 +112,30 @@ fn customizing_spacing_between_x_and_y_ticks() { plot.set_layout(layout); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: customizing_spacing_between_x_and_y_ticks // Heatmaps -fn basic_heat_map() { +// ANCHOR: basic_heat_map +fn basic_heat_map(show: bool) -> Plot { let z = vec![vec![1, 20, 30], vec![20, 1, 60], vec![30, 60, 1]]; let trace = HeatMap::new_z(z).zmin(1.0).zmax(60.0); let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: basic_heat_map -fn customized_heat_map() { +// ANCHOR: customized_heat_map +fn customized_heat_map(show: bool) -> Plot { let x = (0..100).map(|x| x as f64).collect::>(); let y = (0..100).map(|y| y as f64).collect::>(); let z: Vec> = y @@ -143,19 +169,38 @@ fn customized_heat_map() { plot.set_layout(layout); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot +} +// ANCHOR_END: customized_heat_map + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. + // Change false to true on any of these lines to display the example. // Contour Plots - // simple_contour_plot(); - // colorscale_for_contour_plot(); - // customizing_size_and_range_of_a_contour_plots_contours(); - // customizing_spacing_between_x_and_y_ticks(); + write_example_to_html(simple_contour_plot(false), "simple_contour_plot"); + write_example_to_html( + colorscale_for_contour_plot(false), + "colorscale_for_contour_plot", + ); + write_example_to_html( + customizing_size_and_range_of_a_contour_plots_contours(false), + "customizing_size_and_range_of_a_contour_plots_contours", + ); + write_example_to_html( + customizing_spacing_between_x_and_y_ticks(false), + "customizing_spacing_between_x_and_y_ticks", + ); // Heatmaps - // basic_heat_map(); - // customized_heat_map(); + write_example_to_html(basic_heat_map(false), "basic_heat_map"); + write_example_to_html(customized_heat_map(false), "customized_heat_map"); } From 27e4c8a5006ffe93b4e1df844930276da410f6b5 Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 17:07:17 +0000 Subject: [PATCH 3/6] fix rendering of financial charts --- .github/workflows/book.yml | 1 + .../financial_charts/candlestick_charts.md | 89 +------- .../recipes/financial_charts/ohlc_charts.md | 89 +------- .../time_series_and_date_axes.md | 208 ++---------------- examples/financial_charts/src/main.rs | 86 ++++++-- 5 files changed, 95 insertions(+), 378 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 7fd130f..910e738 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -21,6 +21,7 @@ jobs: cd ${{ github.workspace }}/examples/basic_charts && cargo run cd ${{ github.workspace }}/examples/statistical_charts && cargo run cd ${{ github.workspace }}/examples/scientific_charts && cargo run + cd ${{ github.workspace }}/examples/financial_charts && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/recipes/financial_charts/candlestick_charts.md b/docs/book/src/recipes/financial_charts/candlestick_charts.md index 69debd8..0b59ea0 100644 --- a/docs/book/src/recipes/financial_charts/candlestick_charts.md +++ b/docs/book/src/recipes/financial_charts/candlestick_charts.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{TickFormatStop, Title}; use plotly::layout::{Axis, RangeSelector, RangeSlider, SelectorButton, SelectorStep, StepMode}; use plotly::{Candlestick, Layout, Ohlc, Plot, Scatter}; @@ -14,87 +14,8 @@ use std::path::PathBuf; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Simple Candlestick Chart -```rust -fn simple_candlestick_chart(show: bool) { - let x = vec![ - "2017-01-04", - "2017-01-05", - "2017-01-06", - "2017-01-09", - "2017-01-10", - "2017-01-11", - "2017-01-12", - "2017-01-13", - "2017-01-17", - "2017-01-18", - "2017-01-19", - "2017-01-20", - "2017-01-23", - "2017-01-24", - "2017-01-25", - "2017-01-26", - "2017-01-27", - "2017-01-30", - "2017-01-31", - "2017-02-01", - "2017-02-02", - "2017-02-03", - "2017-02-06", - "2017-02-07", - "2017-02-08", - "2017-02-09", - "2017-02-10", - "2017-02-13", - "2017-02-14", - "2017-02-15", - ]; - let open = vec![ - 115.849998, 115.919998, 116.779999, 117.949997, 118.769997, 118.739998, 118.900002, - 119.110001, 118.339996, 120.0, 119.400002, 120.449997, 120.0, 119.550003, 120.419998, - 121.669998, 122.139999, 120.93, 121.150002, 127.029999, 127.980003, 128.309998, 129.130005, - 130.539993, 131.350006, 131.649994, 132.460007, 133.080002, 133.470001, 135.520004, - ]; - let high = vec![ - 116.510002, 116.860001, 118.160004, 119.43, 119.379997, 119.93, 119.300003, 119.620003, - 120.239998, 120.5, 120.089996, 120.449997, 120.809998, 120.099998, 122.099998, 122.440002, - 122.349998, 121.629997, 121.389999, 130.490005, 129.389999, 129.190002, 130.5, 132.089996, - 132.220001, 132.449997, 132.940002, 133.820007, 135.089996, 136.270004, - ]; - let low = vec![ - 115.75, 115.809998, 116.470001, 117.940002, 118.300003, 118.599998, 118.209999, 118.809998, - 118.220001, 119.709999, 119.370003, 119.730003, 119.769997, 119.5, 120.279999, 121.599998, - 121.599998, 120.660004, 120.620003, 127.010002, 127.779999, 128.160004, 128.899994, - 130.449997, 131.220001, 131.119995, 132.050003, 132.75, 133.25, 134.619995, - ]; - let close = vec![ - 116.019997, 116.610001, 117.910004, 118.989998, 119.110001, 119.75, 119.25, 119.040001, - 120.0, 119.989998, 119.779999, 120.0, 120.080002, 119.970001, 121.879997, 121.940002, - 121.949997, 121.629997, 121.349998, 128.75, 128.529999, 129.080002, 130.289993, 131.529999, - 132.039993, 132.419998, 132.119995, 133.289993, 135.020004, 135.509995, - ]; - - let trace1 = Candlestick::new(x, open, high, low, close); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("simple_candlestick_chart")) - ); -} +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:simple_candlestick_chart}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/financial_charts/out/simple_candlestick_chart.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/financial_charts/ohlc_charts.md b/docs/book/src/recipes/financial_charts/ohlc_charts.md index fd77a57..7146b0e 100644 --- a/docs/book/src/recipes/financial_charts/ohlc_charts.md +++ b/docs/book/src/recipes/financial_charts/ohlc_charts.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{TickFormatStop, Title}; use plotly::layout::{Axis, RangeSelector, RangeSlider, SelectorButton, SelectorStep, StepMode}; use plotly::{Candlestick, Layout, Ohlc, Plot, Scatter}; @@ -14,87 +14,8 @@ use std::path::PathBuf; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Simple OHLC Chart -```rust -fn simple_ohlc_chart(show: bool) { - let x = vec![ - "2017-01-04", - "2017-01-05", - "2017-01-06", - "2017-01-09", - "2017-01-10", - "2017-01-11", - "2017-01-12", - "2017-01-13", - "2017-01-17", - "2017-01-18", - "2017-01-19", - "2017-01-20", - "2017-01-23", - "2017-01-24", - "2017-01-25", - "2017-01-26", - "2017-01-27", - "2017-01-30", - "2017-01-31", - "2017-02-01", - "2017-02-02", - "2017-02-03", - "2017-02-06", - "2017-02-07", - "2017-02-08", - "2017-02-09", - "2017-02-10", - "2017-02-13", - "2017-02-14", - "2017-02-15", - ]; - let open = vec![ - 115.849998, 115.919998, 116.779999, 117.949997, 118.769997, 118.739998, 118.900002, - 119.110001, 118.339996, 120.0, 119.400002, 120.449997, 120.0, 119.550003, 120.419998, - 121.669998, 122.139999, 120.93, 121.150002, 127.029999, 127.980003, 128.309998, 129.130005, - 130.539993, 131.350006, 131.649994, 132.460007, 133.080002, 133.470001, 135.520004, - ]; - let high = vec![ - 116.510002, 116.860001, 118.160004, 119.43, 119.379997, 119.93, 119.300003, 119.620003, - 120.239998, 120.5, 120.089996, 120.449997, 120.809998, 120.099998, 122.099998, 122.440002, - 122.349998, 121.629997, 121.389999, 130.490005, 129.389999, 129.190002, 130.5, 132.089996, - 132.220001, 132.449997, 132.940002, 133.820007, 135.089996, 136.270004, - ]; - let low = vec![ - 115.75, 115.809998, 116.470001, 117.940002, 118.300003, 118.599998, 118.209999, 118.809998, - 118.220001, 119.709999, 119.370003, 119.730003, 119.769997, 119.5, 120.279999, 121.599998, - 121.599998, 120.660004, 120.620003, 127.010002, 127.779999, 128.160004, 128.899994, - 130.449997, 131.220001, 131.119995, 132.050003, 132.75, 133.25, 134.619995, - ]; - let close = vec![ - 116.019997, 116.610001, 117.910004, 118.989998, 119.110001, 119.75, 119.25, 119.040001, - 120.0, 119.989998, 119.779999, 120.0, 120.080002, 119.970001, 121.879997, 121.940002, - 121.949997, 121.629997, 121.349998, 128.75, 128.529999, 129.080002, 130.289993, 131.529999, - 132.039993, 132.419998, 132.119995, 133.289993, 135.020004, 135.509995, - ]; - - let trace1 = Ohlc::new(x, open, high, low, close); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("simple_ohlc_chart")) - ); -} +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:simple_ohlc_chart}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/financial_charts/out/simple_ohlc_chart.html}} \ No newline at end of file diff --git a/docs/book/src/recipes/financial_charts/time_series_and_date_axes.md b/docs/book/src/recipes/financial_charts/time_series_and_date_axes.md index 686a93f..580976e 100644 --- a/docs/book/src/recipes/financial_charts/time_series_and_date_axes.md +++ b/docs/book/src/recipes/financial_charts/time_series_and_date_axes.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{TickFormatStop, Title}; use plotly::layout::{Axis, RangeSelector, RangeSlider, SelectorButton, SelectorStep, StepMode}; use plotly::{Candlestick, Layout, Ohlc, Plot, Scatter}; @@ -14,206 +14,32 @@ use std::path::PathBuf; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Time Series Plot with Custom Date Range -```rust -fn time_series_plot_with_custom_date_range(show: bool) { - let data = load_apple_data(); - let date = data.iter().map(|d| d.date.clone()).collect(); - let high = data.iter().map(|d| d.high).collect(); - - let trace = Scatter::new(date, high); - - let mut plot = Plot::new(); - plot.add_trace(trace); - - let layout = Layout::new() - .x_axis(Axis::new().range(vec!["2016-07-01", "2016-12-31"])) - .title(Title::with_text("Manually Set Date Range")); - plot.set_layout(layout); - - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("time_series_plot_with_custom_date_range")) - ); -} - +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:time_series_plot_with_custom_date_range}} ``` -
- +{{#include ../../../../../examples/financial_charts/out/time_series_plot_with_custom_date_range.html}} -## Time Series with Range Slider -```rust -fn time_series_with_range_slider(show: bool) { - let data = load_apple_data(); - let date = data.iter().map(|d| d.date.clone()).collect(); - let high = data.iter().map(|d| d.high).collect(); - let trace = Scatter::new(date, high); - - let mut plot = Plot::new(); - plot.add_trace(trace); - - let layout = Layout::new() - .x_axis(Axis::new().range_slider(RangeSlider::new().visible(true))) - .title(Title::with_text("Manually Set Date Range")); - plot.set_layout(layout); - - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("time_series_with_range_slider")) - ); -} +## Time Series with Range Slider +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:time_series_with_range_slider}} ``` -
- +{{#include ../../../../../examples/financial_charts/out/time_series_with_range_slider.html}} -## Time Series with Range Selector Buttons -```rust -fn time_series_with_range_selector_buttons(show: bool) { - let data = load_apple_data(); - let date = data.iter().map(|d| d.date.clone()).collect(); - let high = data.iter().map(|d| d.high).collect(); - let trace = Scatter::new(date, high); - - let mut plot = Plot::new(); - plot.add_trace(trace); - - let layout = Layout::new().x_axis( - Axis::new() - .range_slider(RangeSlider::new().visible(true)) - .range_selector(RangeSelector::new().buttons(vec![ - SelectorButton::new() - .count(1) - .label("1m") - .step(SelectorStep::Month) - .step_mode(StepMode::Backward), - SelectorButton::new() - .count(6) - .label("6m") - .step(SelectorStep::Month) - .step_mode(StepMode::Backward), - SelectorButton::new() - .count(1) - .label("YTD") - .step(SelectorStep::Year) - .step_mode(StepMode::ToDate), - SelectorButton::new() - .count(1) - .label("1y") - .step(SelectorStep::Year) - .step_mode(StepMode::Backward), - SelectorButton::new().step(SelectorStep::All), - ])), - ); - plot.set_layout(layout); - - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("time_series_with_range_selector_buttons")) - ); -} +## Time Series with Range Selector Buttons +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:time_series_with_range_selector_buttons}} ``` -
- - -## Customizing Tick Label Formatting by Zoom Level -```rust -fn customizing_tick_label_formatting_by_zoom_level(show: bool) { - let data = load_apple_data(); - let date = data.iter().map(|d| d.date.clone()).collect(); - let high = data.iter().map(|d| d.high).collect(); - - let trace = Scatter::new(date, high); - - let mut plot = Plot::new(); - plot.add_trace(trace); +{{#include ../../../../../examples/financial_charts/out/time_series_with_range_selector_buttons.html}} - let layout = Layout::new().x_axis( - Axis::new() - .range_slider(RangeSlider::new().visible(true)) - .tick_format_stops(vec![ - TickFormatStop::new() - .dtick_range(vec![0, 1000]) - .value("%H:%M:%S.%L ms"), - TickFormatStop::new() - .dtick_range(vec![1000, 60000]) - .value("%H:%M:%S s"), - TickFormatStop::new() - .dtick_range(vec![60000, 3600000]) - .value("%H:%M m"), - TickFormatStop::new() - .dtick_range(vec![3600000, 86400000]) - .value("%H:%M h"), - TickFormatStop::new() - .dtick_range(vec![86400000, 604800000]) - .value("%e. %b d"), - TickFormatStop::new() - .dtick_range(vec!["M1", "M12"]) - .value("%b '%y M"), - ]), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("customizing_tick_label_formatting_by_zoom_level")) - ); -} +## Customizing Tick Label Formatting by Zoom Level +```rust,no_run +{{#include ../../../../../examples/financial_charts/src/main.rs:customizing_tick_label_formatting_by_zoom_level}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/financial_charts/out/customizing_tick_label_formatting_by_zoom_level.html}} \ No newline at end of file diff --git a/examples/financial_charts/src/main.rs b/examples/financial_charts/src/main.rs index 1473699..8eb4e0a 100644 --- a/examples/financial_charts/src/main.rs +++ b/examples/financial_charts/src/main.rs @@ -38,7 +38,8 @@ fn load_apple_data() -> Vec { } // Time Series and Date Axes -fn time_series_plot_with_custom_date_range() { +// ANCHOR: time_series_plot_with_custom_date_range +fn time_series_plot_with_custom_date_range(show: bool) -> Plot { let data = load_apple_data(); let date: Vec = data.iter().map(|d| d.date.clone()).collect(); let high: Vec = data.iter().map(|d| d.high).collect(); @@ -53,10 +54,15 @@ fn time_series_plot_with_custom_date_range() { .title("Manually Set Date Range"); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: time_series_plot_with_custom_date_range -fn time_series_with_range_slider() { +// ANCHOR: time_series_with_range_slider +fn time_series_with_range_slider(show: bool) -> Plot { let data = load_apple_data(); let date: Vec = data.iter().map(|d| d.date.clone()).collect(); let high: Vec = data.iter().map(|d| d.high).collect(); @@ -71,10 +77,15 @@ fn time_series_with_range_slider() { .title("Manually Set Date Range"); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: time_series_with_range_slider -fn time_series_with_range_selector_buttons() { +// ANCHOR: time_series_with_range_selector_buttons +fn time_series_with_range_selector_buttons(show: bool) -> Plot { let data = load_apple_data(); let date: Vec = data.iter().map(|d| d.date.clone()).collect(); let high: Vec = data.iter().map(|d| d.high).collect(); @@ -113,10 +124,15 @@ fn time_series_with_range_selector_buttons() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: time_series_with_range_selector_buttons -fn customizing_tick_label_formatting_by_zoom_level() { +// ANCHOR: customizing_tick_label_formatting_by_zoom_level +fn customizing_tick_label_formatting_by_zoom_level(show: bool) -> Plot { let data = load_apple_data(); let date: Vec = data.iter().map(|d| d.date.clone()).collect(); let high: Vec = data.iter().map(|d| d.high).collect(); @@ -152,11 +168,16 @@ fn customizing_tick_label_formatting_by_zoom_level() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: customizing_tick_label_formatting_by_zoom_level // Candlestick Charts -fn simple_candlestick_chart() { +// ANCHOR: simple_candlestick_chart +fn simple_candlestick_chart(show: bool) -> Plot { let x = vec![ "2017-01-04", "2017-01-05", @@ -219,11 +240,16 @@ fn simple_candlestick_chart() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_candlestick_chart // OHLC Charts -fn simple_ohlc_chart() { +// ANCHOR: simple_ohlc_chart +fn simple_ohlc_chart(show: bool) -> Plot { let x = vec![ "2017-01-04", "2017-01-05", @@ -286,21 +312,43 @@ fn simple_ohlc_chart() { let mut plot = Plot::new(); plot.add_trace(trace1); - plot.show(); + if show { + plot.show(); + } + plot +} +// ANCHOR_END: simple_ohlc_chart + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. + // Change false to true on any of these lines to display the example. // Time Series and Date Axes - // time_series_plot_with_custom_date_range(); - // time_series_with_range_slider(); - // time_series_with_range_selector_buttons(); - // customizing_tick_label_formatting_by_zoom_level(); + write_example_to_html( + time_series_plot_with_custom_date_range(false), + "time_series_plot_with_custom_date_range", + ); + write_example_to_html( + time_series_with_range_slider(false), + "time_series_with_range_slider", + ); + write_example_to_html( + time_series_with_range_selector_buttons(false), + "time_series_with_range_selector_buttons", + ); + write_example_to_html( + customizing_tick_label_formatting_by_zoom_level(false), + "customizing_tick_label_formatting_by_zoom_level", + ); // Candlestick Charts - // simple_candlestick_chart(); + write_example_to_html(simple_candlestick_chart(false), "simple_candlestick_chart"); // OHLC Charts - // simple_ohlc_chart(); + write_example_to_html(simple_ohlc_chart(false), "simple_ohlc_chart"); } From 1cb411526a8a9c8811f66c97c80a3e7d922c23af Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 17:32:56 +0000 Subject: [PATCH 4/6] update 3d charts to the new include model --- .github/workflows/book.yml | 1 + docs/book/src/recipes/3dcharts/3dcharts.md | 339 +-------------------- examples/3d_charts/src/main.rs | 77 +++-- 3 files changed, 65 insertions(+), 352 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 910e738..2bf6859 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -22,6 +22,7 @@ jobs: cd ${{ github.workspace }}/examples/statistical_charts && cargo run cd ${{ github.workspace }}/examples/scientific_charts && cargo run cd ${{ github.workspace }}/examples/financial_charts && cargo run + cd ${{ github.workspace }}/examples/3d_charts && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/recipes/3dcharts/3dcharts.md b/docs/book/src/recipes/3dcharts/3dcharts.md index 972562a..4875c9c 100644 --- a/docs/book/src/recipes/3dcharts/3dcharts.md +++ b/docs/book/src/recipes/3dcharts/3dcharts.md @@ -2,8 +2,8 @@ The following imports have been used to produce the plots below: -```rust -use itertools_num::linspace; +```rust,no_run +use ndarray::Array; use plotly::common::{ ColorScale, ColorScalePalette, DashType, Fill, Font, Line, LineShape, Marker, Mode, Title, }; @@ -15,335 +15,8 @@ use rand_distr::{Distribution, Normal, Uniform}; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Constructing a basic Scatter 3D plot -```rust -let n: usize = 100; -let t: Vec = linspace(0., 10., n).collect(); -let y: Vec = t.iter().map(|x| x.sin()).collect(); -let z: Vec = t.iter().map(|x| x.cos()).collect(); - -let trace = Scatter3D::new(t, y, z).mode(Mode::Markers); -let mut plot = Plot::new(); -plot.add_trace(trace); +```rust,no_run +{{#include ../../../../../examples/3d_charts/src/main.rs:simple_scatter3d_plot}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/3d_charts/out/simple_scatter3d_plot.html}} \ No newline at end of file diff --git a/examples/3d_charts/src/main.rs b/examples/3d_charts/src/main.rs index 2281bda..274ab49 100644 --- a/examples/3d_charts/src/main.rs +++ b/examples/3d_charts/src/main.rs @@ -10,7 +10,8 @@ use plotly::{ use rand::Rng; // 3D Scatter Plots -fn simple_scatter3d_plot() { +// ANCHOR: simple_scatter3d_plot +fn simple_scatter3d_plot(show: bool) -> Plot { let n: usize = 100; let t: Vec = Array::linspace(0., 10., n).into_raw_vec_and_offset().0; let y: Vec = t.iter().map(|x| x.sin()).collect(); @@ -20,10 +21,15 @@ fn simple_scatter3d_plot() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_scatter3d_plot -fn customized_scatter3d_plot() { +// ANCHOR: customized_scatter3d_plot +fn customized_scatter3d_plot(show: bool) -> Plot { let n: usize = 100; let t: Vec = Array::linspace(0., 10., n).into_raw_vec_and_offset().0; let y: Vec = t.iter().map(|x| x.sin()).collect(); @@ -108,11 +114,16 @@ fn customized_scatter3d_plot() { .height(500); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: customized_scatter3d_plot // 3D Line Plots -fn simple_line3d_plot() { +// ANCHOR: simple_line3d_plot +fn simple_line3d_plot(show: bool) -> Plot { let n: usize = 100; let t: Vec = Array::linspace(0., 10., n).into_raw_vec_and_offset().0; let y: Vec = t.iter().map(|x| x.sin()).collect(); @@ -122,11 +133,16 @@ fn simple_line3d_plot() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_line3d_plot // 3D Surface Plot -fn surface_plot() { +// ANCHOR: surface_plot +fn surface_plot(show: bool) -> Plot { let n: usize = 100; let x: Vec = Array::linspace(-10., 10., n).into_raw_vec_and_offset().0; let y: Vec = Array::linspace(-10., 10., n).into_raw_vec_and_offset().0; @@ -143,10 +159,15 @@ fn surface_plot() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: surface_plot -fn mesh_3d_plot() { +// ANCHOR: mesh_3d_plot +fn mesh_3d_plot(show: bool) -> Plot { let trace = Mesh3D::new( vec![0, 1, 2, 0], vec![0, 0, 1, 2], @@ -161,10 +182,15 @@ fn mesh_3d_plot() { let mut plot = Plot::new(); plot.add_trace(trace); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: mesh_3d_plot -fn colorscale_plot() { +// ANCHOR: colorscale_plot +fn colorscale_plot(show: bool) -> Plot { let mut plot = Plot::new(); let x = (0..100) @@ -226,21 +252,34 @@ fn colorscale_plot() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot +} +// ANCHOR_END: colorscale_plot + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. + // Change false to true on any of these lines to display the example. // Scatter3D Plots - // simple_scatter3d_plot(); - // simple_line3d_plot(); - // customized_scatter3d_plot(); - // colorscale_plot(); + write_example_to_html(simple_scatter3d_plot(false), "simple_scatter3d_plot"); + write_example_to_html(simple_line3d_plot(false), "simple_line3d_plot"); + write_example_to_html( + customized_scatter3d_plot(false), + "customized_scatter3d_plot", + ); + write_example_to_html(colorscale_plot(false), "colorscale_plot"); // Surface Plots - // surface_plot(); + write_example_to_html(surface_plot(false), "surface_plot"); // Mesh Plots - // mesh_3d_plot(); + write_example_to_html(mesh_3d_plot(false), "mesh_3d_plot"); } From 7f4a98238cab2a5e64c696cbcd335af46584ec40 Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 18:01:45 +0000 Subject: [PATCH 5/6] fix rendering of subplot graphs --- .github/workflows/book.yml | 1 + .../src/recipes/subplots/multiple_axes.md | 121 +------ docs/book/src/recipes/subplots/subplots.md | 297 ++---------------- examples/subplots/src/main.rs | 146 +++++++-- 4 files changed, 147 insertions(+), 418 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 2bf6859..0d7b000 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -23,6 +23,7 @@ jobs: cd ${{ github.workspace }}/examples/scientific_charts && cargo run cd ${{ github.workspace }}/examples/financial_charts && cargo run cd ${{ github.workspace }}/examples/3d_charts && cargo run + cd ${{ github.workspace }}/examples/subplots && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/recipes/subplots/multiple_axes.md b/docs/book/src/recipes/subplots/multiple_axes.md index 6cc3b5d..9b7641e 100644 --- a/docs/book/src/recipes/subplots/multiple_axes.md +++ b/docs/book/src/recipes/subplots/multiple_axes.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{Font, AxisSide, Title}; use plotly::layout::{Axis, GridPattern, Layout, LayoutGrid, Legend, RowOrder}; use plotly::{Plot, Rgb, Scatter}; @@ -11,119 +11,16 @@ use plotly::{Plot, Rgb, Scatter}; The `to_inline_html` method is used to produce the html plot displayed in this page. ## Two Y Axes -```rust -fn two_y_axes(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3], vec![40, 50, 60]).name("trace1"); - let trace2 = Scatter::new(vec![2, 3, 4], vec![4, 5, 6]) - .name("trace2") - .y_axis("y2"); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - - let layout = Layout::new() - .title(Title::with_text("Double Y Axis Example")) - .y_axis(Axis::new().title(Title::with_text("yaxis title"))) - .y_axis2( - Axis::new() - .title(Title::with_text("yaxis2 title").font(Font::new().color(Rgb::new(148, 103, 189)))) - .tick_font(Font::new().color(Rgb::new(148, 103, 189))) - .overlaying("y") - .side(AxisSide::Right), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("two_y_axes"))); -} +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:two_y_axes}} ``` -
- - -## Multiple Axes -```rust -fn multiple_axes(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); - let trace2 = Scatter::new(vec![2, 3, 4], vec![40, 50, 60]) - .name("trace2") - .y_axis("y2"); - let trace3 = Scatter::new(vec![4, 5, 6], vec![40_000, 50_000, 60_000]).y_axis("y3"); - let trace4 = Scatter::new(vec![5, 6, 7], vec![400_000, 500_000, 600_000]).y_axis("y4"); +{{#include ../../../../../examples/subplots/out/two_y_axes.html}} - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - plot.add_trace(trace4); - let layout = Layout::new() - .title(Title::with_text("multiple y-axes example")) - .width(800) - .x_axis(Axis::new().domain(&[0.3, 0.7])) - .y_axis( - Axis::new() - .title(Title::with_text("yaxis title").font(Font::new().color("#1f77b4"))) - .tick_font(Font::new().color("#1f77b4")), - ) - .y_axis2( - Axis::new() - .title(Title::with_text("yaxis2 title").font(Font::new().color("#ff7f0e"))) - .tick_font(Font::new().color("#ff7f0e")) - .anchor("free") - .overlaying("y") - .side(AxisSide::Left) - .position(0.15), - ) - .y_axis3( - Axis::new() - .title(Title::with_text("yaxis3 title").font(Font::new().color("#d62728"))) - .tick_font(Font::new().color("#d62728")) - .anchor("x") - .overlaying("y") - .side(AxisSide::Right), - ) - .y_axis4( - Axis::new() - .title(Title::with_text("yaxis4 title").font(Font::new().color("#9467bd"))) - .tick_font(Font::new().color("#9467bd")) - .anchor("free") - .overlaying("y") - .side(AxisSide::Right) - .position(0.85), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("multiple_axes"))); -} +## Multiple Axes +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:multiple_axes}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/subplots/out/multiple_axes.html}} diff --git a/docs/book/src/recipes/subplots/subplots.md b/docs/book/src/recipes/subplots/subplots.md index 75fc75a..e9da1d6 100644 --- a/docs/book/src/recipes/subplots/subplots.md +++ b/docs/book/src/recipes/subplots/subplots.md @@ -2,7 +2,7 @@ The following imports have been used to produce the plots below: -```rust +```rust,no_run use plotly::common::{Font, Side, Title}; use plotly::layout::{Axis, GridPattern, Layout, LayoutGrid, Legend, RowOrder}; use plotly::{Plot, Rgb, Scatter}; @@ -12,295 +12,48 @@ The `to_inline_html` method is used to produce the html plot displayed in this p ## Simple Subplot -```rust -fn simple_subplot(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); - let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) - .name("trace2") - .x_axis("x2") - .y_axis("y2"); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - - let layout = Layout::new().grid( - LayoutGrid::new() - .rows(1) - .columns(2) - .pattern(GridPattern::Independent), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("simple_subplot")) - ); -} +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:simple_subplot}} ``` -
- +{{#include ../../../../../examples/subplots/out/simple_subplot.html}} -## Custom Sized Subplot -```rust -fn custom_sized_subplot(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); - let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) - .name("trace2") - .x_axis("x2") - .y_axis("y2"); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - - let layout = Layout::new() - .x_axis(Axis::new().domain(&[0., 0.7])) - .y_axis2(Axis::new().anchor("x2")) - .x_axis2(Axis::new().domain(&[0.8, 1.])); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("custom_sized_subplot")) - ); -} +## Custom Sized Subplot +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:custom_sized_subplot}} ``` -
- +{{#include ../../../../../examples/subplots/out/custom_sized_subplot.html}} -## Multiple Subplots -```rust -fn multiple_subplots(show: bool) { - let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); - let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) - .name("trace2") - .x_axis("x2") - .y_axis("y2"); - let trace3 = Scatter::new(vec![300, 400, 500], vec![600, 700, 800]) - .x_axis("x3") - .y_axis("y3"); - let trace4 = Scatter::new(vec![4000, 5000, 6000], vec![7000, 8000, 9000]) - .x_axis("x4") - .y_axis("y4"); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - plot.add_trace(trace4); - let layout = Layout::new().grid( - LayoutGrid::new() - .rows(2) - .columns(2) - .pattern(GridPattern::Independent), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("multiple_subplots")) - ); -} +## Multiple Subplots +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:multiple_subplots}} ``` -
- - -## Stacked Subplots -```rust -fn stacked_subplots(show: bool) { - let trace1 = Scatter::new(vec![0, 1, 2], vec![10, 11, 12]).name("trace1"); - let trace2 = Scatter::new(vec![2, 3, 4], vec![100, 110, 120]) - .name("trace2") - .x_axis("x2") - .y_axis("y2"); - let trace3 = Scatter::new(vec![3, 4, 5], vec![1000, 1100, 1200]) - .x_axis("x3") - .y_axis("y3"); +{{#include ../../../../../examples/subplots/out/multiple_subplots.html}} - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - let layout = Layout::new().grid( - LayoutGrid::new() - .rows(3) - .columns(1) - .pattern(GridPattern::Independent) - .row_order(RowOrder::BottomToTop), - ); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("stacked_subplots")) - ); -} +## Stacked Subplots +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:stacked_subplots}} ``` -
- +{{#include ../../../../../examples/subplots/out/stacked_subplots.html}} -## Stacked Subplots with Shared X Axis -```rust -fn stacked_subplots_with_shared_x_axis(show: bool) { - let trace1 = Scatter::new(vec![0, 1, 2], vec![10, 11, 12]).name("trace1"); - let trace2 = Scatter::new(vec![2, 3, 4], vec![100, 110, 120]) - .name("trace2") - .y_axis("y2"); - let trace3 = Scatter::new(vec![3, 4, 5], vec![1000, 1100, 1200]).y_axis("y3"); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - - let layout = Layout::new() - .y_axis(Axis::new().domain(&[0., 0.33])) - .legend(Legend::new().trace_order("reversed")) - .y_axis2(Axis::new().domain(&[0.33, 0.66])) - .y_axis3(Axis::new().domain(&[0.66, 1.])); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("stacked_subplots_with_shared_x_axis")) - ); -} +## Stacked Subplots with Shared X Axis +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:stacked_subplots_with_shared_x_axis}} ``` -
- +{{#include ../../../../../examples/subplots/out/stacked_subplots_with_shared_x_axis.html}} -## Multiple Custom Sized Subplots -```rust -fn multiple_custom_sized_subplots(show: bool) { - let trace1 = Scatter::new(vec![1, 2], vec![1, 2]).name("(1,1)"); - let trace2 = Scatter::new(vec![1, 2], vec![1, 2]) - .name("(1,2,1)") - .x_axis("x2") - .y_axis("y2"); - let trace3 = Scatter::new(vec![1, 2], vec![1, 2]) - .name("(1,2,2)") - .x_axis("x3") - .y_axis("y3"); - let trace4 = Scatter::new(vec![1, 2], vec![1, 2]) - .name("{(2,1), (2,2)}") - .x_axis("x4") - .y_axis("y4"); - - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - plot.add_trace(trace3); - plot.add_trace(trace4); - let layout = Layout::new() - .title(Title::with_text("Multiple Custom Sized Subplots")) - .x_axis(Axis::new().domain(&[0., 0.45]).anchor("y1")) - .y_axis(Axis::new().domain(&[0.5, 1.]).anchor("x1")) - .x_axis2(Axis::new().domain(&[0.55, 1.]).anchor("y2")) - .y_axis2(Axis::new().domain(&[0.8, 1.]).anchor("x2")) - .x_axis3(Axis::new().domain(&[0.55, 1.]).anchor("y3")) - .y_axis3(Axis::new().domain(&[0.5, 0.75]).anchor("x3")) - .x_axis4(Axis::new().domain(&[0., 1.]).anchor("y4")) - .y_axis4(Axis::new().domain(&[0., 0.45]).anchor("x4")); - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("multiple_custom_sized_subplots")) - ); -} +## Multiple Custom Sized Subplots +```rust,no_run +{{#include ../../../../../examples/subplots/src/main.rs:multiple_custom_sized_subplots}} ``` -
- \ No newline at end of file + +{{#include ../../../../../examples/subplots/out/multiple_custom_sized_subplots.html}} \ No newline at end of file diff --git a/examples/subplots/src/main.rs b/examples/subplots/src/main.rs index c78bde5..7806c48 100644 --- a/examples/subplots/src/main.rs +++ b/examples/subplots/src/main.rs @@ -6,8 +6,10 @@ use plotly::layout::{ }; use plotly::Configuration; use plotly::{color::Rgb, Plot, Scatter}; + // Subplots -fn simple_subplot() { +// ANCHOR: simple_subplot +fn simple_subplot(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) .name("trace2") @@ -26,10 +28,15 @@ fn simple_subplot() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_subplot -fn simple_subplot_matches_x_axis() { +// ANCHOR: simple_subplot_matches_x_axis +fn simple_subplot_matches_x_axis(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) .name("trace2") @@ -48,10 +55,15 @@ fn simple_subplot_matches_x_axis() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_subplot_matches_x_axis -fn simple_subplot_matches_y_axis() { +// ANCHOR: simple_subplot_matches_y_axis +fn simple_subplot_matches_y_axis(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) .name("trace2") @@ -70,10 +82,15 @@ fn simple_subplot_matches_y_axis() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: simple_subplot_matches_y_axis -fn custom_sized_subplot() { +// ANCHOR: custom_sized_subplot +fn custom_sized_subplot(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) .name("trace2") @@ -90,10 +107,15 @@ fn custom_sized_subplot() { .x_axis2(Axis::new().domain(&[0.8, 1.])); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: custom_sized_subplot -fn multiple_subplots() { +// ANCHOR: multiple_subplots +fn multiple_subplots(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![20, 30, 40], vec![50, 60, 70]) .name("trace2") @@ -120,10 +142,15 @@ fn multiple_subplots() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: multiple_subplots -fn stacked_subplots() { +// ANCHOR: stacked_subplots +fn stacked_subplots(show: bool) -> Plot { let trace1 = Scatter::new(vec![0, 1, 2], vec![10, 11, 12]).name("trace1"); let trace2 = Scatter::new(vec![2, 3, 4], vec![100, 110, 120]) .name("trace2") @@ -147,10 +174,15 @@ fn stacked_subplots() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: stacked_subplots -fn stacked_subplots_with_shared_x_axis() { +// ANCHOR: stacked_subplots_with_shared_x_axis +fn stacked_subplots_with_shared_x_axis(show: bool) -> Plot { let trace1 = Scatter::new(vec![0, 1, 2], vec![10, 11, 12]).name("trace1"); let trace2 = Scatter::new(vec![2, 3, 4], vec![100, 110, 120]) .name("trace2") @@ -169,10 +201,15 @@ fn stacked_subplots_with_shared_x_axis() { .y_axis3(Axis::new().domain(&[0.66, 1.])); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: stacked_subplots_with_shared_x_axis -fn multiple_custom_sized_subplots() { +// ANCHOR: multiple_custom_sized_subplots +fn multiple_custom_sized_subplots(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2], vec![1, 2]).name("(1,1)"); let trace2 = Scatter::new(vec![1, 2], vec![1, 2]) .name("(1,2,1)") @@ -205,11 +242,16 @@ fn multiple_custom_sized_subplots() { .y_axis4(Axis::new().domain(&[0., 0.45]).anchor("x4")); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: multiple_custom_sized_subplots // Multiple Axes -fn two_y_axes() { +// ANCHOR: two_y_axes +fn two_y_axes(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![40, 50, 60]).name("trace1"); let trace2 = Scatter::new(vec![2, 3, 4], vec![4, 5, 6]) .name("trace2") @@ -231,10 +273,15 @@ fn two_y_axes() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: two_y_axes -fn multiple_axes() { +// ANCHOR: multiple_axes +fn multiple_axes(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2, 3], vec![4, 5, 6]).name("trace1"); let trace2 = Scatter::new(vec![2, 3, 4], vec![40, 50, 60]) .name("trace2") @@ -285,10 +332,15 @@ fn multiple_axes() { ); plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: multiple_axes -fn many_subplots_with_titles() { +// ANCHOR: many_subplots_with_titles +fn many_subplots_with_titles(show: bool) -> Plot { let trace1 = Scatter::new(vec![1, 2], vec![4, 5]); let number_of_plots = 10; @@ -325,24 +377,50 @@ fn many_subplots_with_titles() { plot.set_layout(layout); plot.set_configuration(Configuration::new().responsive(true)); - plot.show(); + + if show { + plot.show(); + } + plot +} +// ANCHOR_END: many_subplots_with_titles + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. + // Change false to true on any of these lines to display the example. // Subplots - // simple_subplot(); - // simple_subplot_matches_x_axis(); - // simple_subplot_matches_y_axis(); - // custom_sized_subplot(); - // multiple_subplots(); - // stacked_subplots(); - // stacked_subplots_with_shared_x_axis(); - // multiple_custom_sized_subplots(); - // many_subplots_with_titles(); + write_example_to_html(simple_subplot(false), "simple_subplot"); + write_example_to_html( + simple_subplot_matches_x_axis(false), + "simple_subplot_matches_x_axis", + ); + write_example_to_html( + simple_subplot_matches_y_axis(false), + "simple_subplot_matches_y_axis", + ); + write_example_to_html(custom_sized_subplot(false), "custom_sized_subplot"); + write_example_to_html(multiple_subplots(false), "multiple_subplots"); + write_example_to_html(stacked_subplots(false), "stacked_subplots"); + write_example_to_html( + stacked_subplots_with_shared_x_axis(false), + "stacked_subplots_with_shared_x_axis", + ); + write_example_to_html( + multiple_custom_sized_subplots(false), + "multiple_custom_sized_subplots", + ); + write_example_to_html( + many_subplots_with_titles(false), + "many_subplots_with_titles", + ); // Multiple Axes - // two_y_axes(); - // multiple_axes(); + write_example_to_html(two_y_axes(false), "two_y_axes"); + write_example_to_html(multiple_axes(false), "multiple_axes"); } From 49eca22a6b3e4566e90929f345e8906dc74c5e5c Mon Sep 17 00:00:00 2001 From: Nick Pearson Date: Sat, 23 Nov 2024 18:41:02 +0000 Subject: [PATCH 6/6] fix rendering of shapes graphs --- .github/workflows/book.yml | 1 + docs/book/src/fundamentals/shapes.md | 951 ++------------------------- examples/shapes/src/main.rs | 173 +++-- 3 files changed, 185 insertions(+), 940 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 0d7b000..7fbe39d 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -24,6 +24,7 @@ jobs: cd ${{ github.workspace }}/examples/financial_charts && cargo run cd ${{ github.workspace }}/examples/3d_charts && cargo run cd ${{ github.workspace }}/examples/subplots && cargo run + cd ${{ github.workspace }}/examples/shapes && cargo run - run: mdbook build docs/book - name: Checkout gh-pages branch run: | diff --git a/docs/book/src/fundamentals/shapes.md b/docs/book/src/fundamentals/shapes.md index 03d4083..4c34d68 100644 --- a/docs/book/src/fundamentals/shapes.md +++ b/docs/book/src/fundamentals/shapes.md @@ -2,8 +2,8 @@ The following imports have been used to produce the plots below: -```rust -use itertools_num::linspace; +```rust,no_run +use ndarray::Array; use plotly::common::{ Fill, Font, Mode, }; @@ -20,947 +20,96 @@ The `to_inline_html` method is used to produce the html plot displayed in this p ## Filled Area Chart -```rust -fn filled_area_chart(show: bool) { - let trace1 = Scatter::new(vec![0, 1, 2, 0], vec![0, 2, 0, 0]).fill(Fill::ToSelf); - let trace2 = - Scatter::new(vec![3, 3, 5, 5, 3], vec![0.5, 1.5, 1.5, 0.5, 0.5]).fill(Fill::ToSelf); - let mut plot = Plot::new(); - plot.add_trace(trace1); - plot.add_trace(trace2); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("filled_area_chart"))); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:filled_area_chart}} ``` -
- + +{{#include ../../../../examples/shapes/out/filled_area_chart.html}} ## Vertical and Horizontal Lines Positioned Relative to Axes -```rust -fn vertical_and_horizontal_lines_positioned_relative_to_axes(show: bool) { - let trace = Scatter::new(vec![2.0, 3.5, 6.0], vec![1.0, 1.5, 1.0]) - .text_array(vec![ - "Vertical Line", - "Horizontal Dashed Line", - "Diagonal dotted Line", - ]) - .mode(Mode::Text); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new() - .x_axis(Axis::new().range(vec![0.0, 7.0])) - .y_axis(Axis::new().range(vec![0.0, 2.5])); - - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Line) - .x0(1) - .y0(0) - .x1(1) - .y1(2) - .line(ShapeLine::new().color(NamedColor::RoyalBlue).width(3.)), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Line) - .x0(2) - .y0(2) - .x1(5) - .y1(2) - .line( - ShapeLine::new() - .color(NamedColor::LightSeaGreen) - .width(3.) - .dash("dashdot"), - ), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Line) - .x0(4) - .y0(0) - .x1(6) - .y1(2) - .line( - ShapeLine::new() - .color(NamedColor::MediumPurple) - .width(3.) - .dash("dot"), - ), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "vertical_and_horizontal_lines_positioned_relative_to_axes" - )) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:vertical_and_horizontal_lines_positioned_relative_to_axes}} ``` -
- + +{{#include ../../../../examples/shapes/out/vertical_and_horizontal_lines_positioned_relative_to_axes.html}} ## Lines Positioned Relative to the Plot and to the Axes -```rust -fn lines_positioned_relative_to_the_plot_and_to_the_axes(show: bool) { - let trace = Scatter::new(vec![2.0, 6.0], vec![1.0, 1.0]) - .text_array(vec![ - "Line positioned relative to the plot", - "Line positioned relative to the axes", - ]) - .mode(Mode::Text); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new() - .x_axis(Axis::new().range(vec![0.0, 8.0])) - .y_axis(Axis::new().range(vec![0.0, 2.])); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Line) - .x0(4) - .y0(0) - .x1(8) - .y1(1) - .line(ShapeLine::new().color(NamedColor::LightSeaGreen).width(3.)), - ); - layout.add_shape( - Shape::new() - .x_ref("paper") - .y_ref("paper") - .shape_type(ShapeType::Line) - .x0(0.0) - .y0(0.0) - .x1(0.5) - .y1(0.5) - .line(ShapeLine::new().color(NamedColor::DarkOrange).width(3.)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "lines_positioned_relative_to_the_plot_and_to_the_axes" - )) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:lines_positioned_relative_to_the_plot_and_to_the_axes}} ``` -
- + +{{#include ../../../../examples/shapes/out/lines_positioned_relative_to_the_plot_and_to_the_axes.html}} ## Creating Tangent Lines with Shapes -```rust -fn creating_tangent_lines_with_shapes(show: bool) { - let x0: Vec = linspace(1.0, 3.0, 200).collect(); - let y0: Vec = x0.iter().map(|v| *v * (v.powf(2.)).sin() + 1.).collect(); - - let trace = Scatter::new(x0, y0); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = - Layout::new().title("$f(x)=x\\sin(x^2)+1\\\\ f\'(x)=\\sin(x^2)+2x^2\\cos(x^2)$".into()); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .opacity(0.7) - .shape_type(ShapeType::Line) - .x0(1.) - .y0(2.30756) - .x1(1.75) - .y1(2.30756) - .line(ShapeLine::new().color(NamedColor::Crimson).width(2.5)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .opacity(0.7) - .shape_type(ShapeType::Line) - .x0(2.5) - .y0(3.80796) - .x1(3.05) - .y1(3.80796) - .line(ShapeLine::new().color(NamedColor::Crimson).width(2.5)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .opacity(0.7) - .shape_type(ShapeType::Line) - .x0(1.90) - .y0(-1.1827) - .x1(2.5) - .y1(-1.1827) - .line(ShapeLine::new().color(NamedColor::Crimson).width(2.5)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("creating_tangent_lines_with_shapes")) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:creating_tangent_lines_with_shapes}} ``` -
- + +{{#include ../../../../examples/shapes/out/creating_tangent_lines_with_shapes.html}} ## Rectangles Positioned Relative to the Axes -```rust -fn rectangles_positioned_relative_to_the_axes(show: bool) { - let trace = Scatter::new(vec![1.5, 4.5], vec![0.75, 0.75]) - .text_array(vec!["Unfilled Rectangle", "Filled Rectangle"]) - .mode(Mode::Text); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new() - .x_axis(Axis::new().range(vec![0.0, 7.0]).show_grid(false)) - .y_axis(Axis::new().range(vec![0.0, 3.5])); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Rect) - .x0(1.) - .y0(1.) - .x1(2.) - .y1(3.) - .line(ShapeLine::new().color(NamedColor::RoyalBlue)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Rect) - .x0(3.) - .y0(1.) - .x1(6.) - .y1(2.) - .line(ShapeLine::new().color(NamedColor::RoyalBlue).width(2.)) - .fill_color(NamedColor::LightSkyBlue), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("rectangles_positioned_relative_to_the_axes")) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:rectangles_positioned_relative_to_the_axes}} ``` -
- + +{{#include ../../../../examples/shapes/out/rectangles_positioned_relative_to_the_axes.html}} ## Rectangle Positioned Relative to the Plot and to the Axes -```rust -fn rectangle_positioned_relative_to_the_plot_and_to_the_axes(show: bool) { - let trace = Scatter::new(vec![1.5, 3.], vec![2.5, 2.5]) - .text_array(vec![ - "Rectangle reference to the plot", - "Rectangle reference to the axes", - ]) - .mode(Mode::Text); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new() - .x_axis(Axis::new().range(vec![0.0, 4.0]).show_grid(false)) - .y_axis(Axis::new().range(vec![0.0, 4.0])); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Rect) - .x0(2.5) - .y0(0.0) - .x1(3.5) - .y1(2.0) - .line(ShapeLine::new().color(NamedColor::RoyalBlue).width(3.)) - .fill_color(NamedColor::LightSkyBlue), - ); - layout.add_shape( - Shape::new() - .x_ref("paper") - .y_ref("paper") - .shape_type(ShapeType::Rect) - .x0(0.25) - .y0(0.0) - .x1(0.5) - .y1(0.5) - .line(ShapeLine::new().color(NamedColor::LightSeaGreen).width(3.)) - .fill_color(NamedColor::PaleTurquoise), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "rectangle_positioned_relative_to_the_plot_and_to_the_axes" - )) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:rectangle_positioned_relative_to_the_plot_and_to_the_axes}} ``` -
- + +{{#include ../../../../examples/shapes/out/rectangle_positioned_relative_to_the_plot_and_to_the_axes.html}} ## Highlighting Time Series Regions with Rectangle Shapes -```rust -fn highlighting_time_series_regions_with_rectangle_shapes(show: bool) { - let x = vec![ - "2015-02-01", - "2015-02-02", - "2015-02-03", - "2015-02-04", - "2015-02-05", - "2015-02-06", - "2015-02-07", - "2015-02-08", - "2015-02-09", - "2015-02-10", - "2015-02-11", - "2015-02-12", - "2015-02-13", - "2015-02-14", - "2015-02-15", - "2015-02-16", - "2015-02-17", - "2015-02-18", - "2015-02-19", - "2015-02-20", - "2015-02-21", - "2015-02-22", - "2015-02-23", - "2015-02-24", - "2015-02-25", - "2015-02-26", - "2015-02-27", - "2015-02-28", - ]; - let y = vec![ - -14, -17, -8, -4, -7, -10, -12, -14, -12, -7, -11, -7, -18, -14, -14, -16, -13, -7, -8, - -14, -8, -3, -9, -9, -4, -13, -9, -6, - ]; - let trace = Scatter::new(x, y).mode(Mode::Lines).name("temperature"); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new(); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("paper") - .shape_type(ShapeType::Rect) - .x0("2015-02-04") - .y0(0) - .x1("2015-02-06") - .y1(1) - .fill_color(NamedColor::LightSalmon) - .opacity(0.5) - .layer(ShapeLayer::Below) - .line(ShapeLine::new().width(0.)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("paper") - .shape_type(ShapeType::Rect) - .x0("2015-02-20") - .y0(0) - .x1("2015-02-22") - .y1(1) - .fill_color(NamedColor::LightSalmon) - .opacity(0.5) - .layer(ShapeLayer::Below) - .line(ShapeLine::new().width(0.)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "highlighting_time_series_regions_with_rectangle_shapes" - )) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:highlighting_time_series_regions_with_rectangle_shapes}} ``` -
- + +{{#include ../../../../examples/shapes/out/highlighting_time_series_regions_with_rectangle_shapes.html}} ## Circles Positioned Relative to the Axes -```rust -fn circles_positioned_relative_to_the_axes(show: bool) { - let trace = Scatter::new(vec![1.5, 3.5], vec![0.75, 2.5]) - .text_array(vec!["Unfilled Circle", "Filled Circle"]) - .mode(Mode::Text); - let mut plot = Plot::new(); - plot.add_trace(trace); - - let mut layout = Layout::new() - .x_axis(Axis::new().range(vec![0.0, 4.5]).zero_line(false)) - .y_axis(Axis::new().range(vec![0.0, 4.5])) - .width(800) - .height(800); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(1) - .y0(1) - .x1(3) - .y1(3) - .line(ShapeLine::new().color(NamedColor::LightSeaGreen)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(3) - .y0(3) - .x1(4) - .y1(4) - .line(ShapeLine::new().color(NamedColor::LightSeaGreen)) - .fill_color(NamedColor::PaleTurquoise), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("circles_positioned_relative_to_the_axes")) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:circles_positioned_relative_to_the_axes}} ``` -
- + +{{#include ../../../../examples/shapes/out/circles_positioned_relative_to_the_axes.html}} ## Highlighting Clusters of Scatter Points with Circle Shapes -```rust -fn highlighting_clusters_of_scatter_points_with_circle_shapes(show: bool) { - let rng = thread_rng(); - let x0 = Normal::new(2., 0.45) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - let y0 = Normal::new(2., 0.45) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - let x1 = Normal::new(6., 0.4) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - let y1 = Normal::new(6., 0.4) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - let x2 = Normal::new(4., 0.3) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - let y2 = Normal::new(4., 0.3) - .unwrap() - .sample_iter(rng) - .take(300) - .collect::>(); - - let x0min = x0.iter().copied().fold(f64::NAN, f64::min); - let x0max = x0.iter().copied().fold(f64::NAN, f64::max); - let y0min = y0.iter().copied().fold(f64::NAN, f64::min); - let y0max = y0.iter().copied().fold(f64::NAN, f64::max); - - let x1min = x1.iter().copied().fold(f64::NAN, f64::min); - let x1max = x1.iter().copied().fold(f64::NAN, f64::max); - let y1min = y1.iter().copied().fold(f64::NAN, f64::min); - - let x2min = x2.iter().copied().fold(f64::NAN, f64::min); - let x2max = x2.iter().copied().fold(f64::NAN, f64::max); - let y2min = y2.iter().copied().fold(f64::NAN, f64::min); - - let mut plot = Plot::new(); - plot.add_trace(Scatter::new(x0, y0.clone()).mode(Mode::Markers)); - plot.add_trace(Scatter::new(x1.clone(), y1).mode(Mode::Markers)); - plot.add_trace(Scatter::new(x2, y2).mode(Mode::Markers)); - plot.add_trace(Scatter::new(x1, y0).mode(Mode::Markers)); - - let mut layout = Layout::new().show_legend(false); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(x0min) - .y0(y0min) - .x1(x0max) - .y1(y0max) - .opacity(0.2) - .fill_color(NamedColor::Blue) - .line(ShapeLine::new().color(NamedColor::Blue)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(x1min) - .y0(y1min) - .x1(x1max) - .y1(x1max) - .opacity(0.2) - .fill_color(NamedColor::Orange) - .line(ShapeLine::new().color(NamedColor::Orange)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(x2min) - .y0(y2min) - .x1(x2max) - .y1(x2max) - .opacity(0.2) - .fill_color(NamedColor::Green) - .line(ShapeLine::new().color(NamedColor::Green)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(x1min) - .y0(y0min) - .x1(x1max) - .y1(x0max) - .opacity(0.2) - .fill_color(NamedColor::Red) - .line(ShapeLine::new().color(NamedColor::Red)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some( - "highlighting_clusters_of_scatter_points_with_circle_shapes" - )) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:highlighting_clusters_of_scatter_points_with_circle_shapes}} ``` -
- + +{{#include ../../../../examples/shapes/out/highlighting_clusters_of_scatter_points_with_circle_shapes.html}} ## Venn Diagram with Circle Shapes -```rust -fn venn_diagram_with_circle_shapes(show: bool) { - let mut plot = Plot::new(); - plot.add_trace( - Scatter::new(vec![1., 1.75, 2.5], vec![1., 1., 1.]) - .text_array(vec!["$A$", "$A+B$", "$B$"]) - .mode(Mode::Text) - .text_font( - Font::new() - .color(NamedColor::Black) - .size(18) - .family("Arial"), - ), - ); - - let mut layout = Layout::new() - .x_axis( - Axis::new() - .zero_line(false) - .show_grid(false) - .show_tick_labels(false), - ) - .y_axis( - Axis::new() - .zero_line(false) - .show_grid(false) - .show_tick_labels(false), - ) - .margin(Margin::new().left(20).right(20).bottom(100)) - .height(600) - .width(800) - .plot_background_color(NamedColor::White); - - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(0) - .y0(0) - .x1(2) - .y1(2) - .opacity(0.3) - .layer(ShapeLayer::Below) - .fill_color(NamedColor::Blue) - .line(ShapeLine::new().color(NamedColor::Blue)), - ); - layout.add_shape( - Shape::new() - .x_ref("x") - .y_ref("y") - .shape_type(ShapeType::Circle) - .x0(1.5) - .y0(0.) - .x1(3.5) - .y1(2.) - .opacity(0.3) - .layer(ShapeLayer::Below) - .fill_color(NamedColor::Gray) - .line(ShapeLine::new().color(NamedColor::Gray)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!( - "{}", - plot.to_inline_html(Some("venn_diagram_with_circle_shapes")) - ); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:venn_diagram_with_circle_shapes}} ``` -
- + +{{#include ../../../../examples/shapes/out/venn_diagram_with_circle_shapes.html}} ## Adding Shapes to Subplots -```rust -fn adding_shapes_to_subplots(show: bool) { - let mut plot = Plot::new(); - plot.add_trace( - Scatter::new(vec![2, 6], vec![1, 1]) - .x_axis("x1") - .y_axis("y1"), - ); - plot.add_trace( - Bar::new(vec![1, 2, 3], vec![4, 5, 6]) - .x_axis("x2") - .y_axis("y2"), - ); - plot.add_trace( - Scatter::new(vec![10, 20], vec![40, 50]) - .x_axis("x3") - .y_axis("y3"), - ); - plot.add_trace( - Bar::new(vec![11, 13, 15], vec![8, 11, 20]) - .x_axis("x4") - .y_axis("y4"), - ); - - let mut layout = Layout::new() - .grid( - LayoutGrid::new() - .rows(2) - .columns(2) - .pattern(GridPattern::Independent), - ) - .x_axis(Axis::new().domain(&[0.0, 0.48]).anchor("x1")) - .y_axis(Axis::new().domain(&[0.52, 1.]).anchor("y1")) - .x_axis2(Axis::new().domain(&[0.52, 1.0]).anchor("x2")) - .y_axis2(Axis::new().domain(&[0.5, 1.]).anchor("y2")) - .x_axis3(Axis::new().domain(&[0.0, 0.48]).anchor("x3")) - .y_axis3(Axis::new().domain(&[0.0, 0.48]).anchor("y3")) - .x_axis4(Axis::new().domain(&[0.52, 1.0]).anchor("x4")) - .y_axis4(Axis::new().domain(&[0.0, 0.48]).anchor("y4")); - - layout.add_shape( - Shape::new() - .x_ref("x1") - .y_ref("y1") - .shape_type(ShapeType::Line) - .x0(3) - .y0(0.5) - .x1(5) - .y1(0.8) - .line(ShapeLine::new().width(3.)), - ); - layout.add_shape( - Shape::new() - .x_ref("x2") - .y_ref("y2") - .shape_type(ShapeType::Rect) - .x0(4) - .y0(2) - .x1(5) - .y1(6), - ); - layout.add_shape( - Shape::new() - .x_ref("x3") - .y_ref("y3") - .shape_type(ShapeType::Rect) - .x0(10) - .y0(20) - .x1(15) - .y1(30), - ); - layout.add_shape( - Shape::new() - .x_ref("x4") - .y_ref("y4") - .shape_type(ShapeType::Circle) - .x0(5) - .y0(12) - .x1(10) - .y1(18), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("adding_shapes_to_subplots"))); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:adding_shapes_to_subplots}} ``` -
- + +{{#include ../../../../examples/shapes/out/adding_shapes_to_subplots.html}} ## SVG Paths -```rust -fn svg_paths(show: bool) { - let mut plot = Plot::new(); - plot.add_trace( - Scatter::new(vec![2, 1, 8, 8], vec![0.25, 9., 2., 6.]) - .text_array(vec![ - "Filled Triangle", - "Filled Polygon", - "Quadratic Bezier Curves", - "Cubic Bezier Curves", - ]) - .mode(Mode::Text), - ); - - let mut layout = Layout::new() - .x_axis( - Axis::new() - .domain(&[0.05, 0.95]) - .range(vec![0., 9.]) - .zero_line(false), - ) - .y_axis( - Axis::new() - .domain(&[0.05, 0.95]) - .range(vec![0, 11]) - .zero_line(false), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Path) - .path("M 4,4 Q 6,0 8,4") - .line(ShapeLine::new().color(NamedColor::RoyalBlue)), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Path) - .path("M 1,4 C 2,8 6,4 8,8") - .line(ShapeLine::new().color(NamedColor::MediumPurple)), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Path) - .path("M 1 1 L 1 3 L 4 1 Z") - .fill_color(NamedColor::LightPink) - .line(ShapeLine::new().color(NamedColor::Crimson)), - ); - layout.add_shape( - Shape::new() - .shape_type(ShapeType::Path) - .path("M 3,7 L2,8 L2,9 L3,10, L4,10 L5,9 L5,8 L4,7 Z") - .fill_color(NamedColor::PaleTurquoise) - .line(ShapeLine::new().color(NamedColor::LightSeaGreen)), - ); - - plot.set_layout(layout); - if show { - plot.show(); - } - println!("{}", plot.to_inline_html(Some("svg_paths"))); -} +```rust,no_run +{{#include ../../../../examples/shapes/src/main.rs:svg_paths}} ``` -
- + +{{#include ../../../../examples/shapes/out/svg_paths.html}} diff --git a/examples/shapes/src/main.rs b/examples/shapes/src/main.rs index 0554ad6..a00864b 100644 --- a/examples/shapes/src/main.rs +++ b/examples/shapes/src/main.rs @@ -12,7 +12,8 @@ use plotly::{ use rand::thread_rng; use rand_distr::{num_traits::Float, Distribution, Normal}; -fn filled_area_chart() { +// ANCHOR: filled_area_chart +fn filled_area_chart(show: bool) -> Plot { let trace1 = Scatter::new(vec![0, 1, 2, 0], vec![0, 2, 0, 0]).fill(Fill::ToSelf); let trace2 = Scatter::new(vec![3, 3, 5, 5, 3], vec![0.5, 1.5, 1.5, 0.5, 0.5]).fill(Fill::ToSelf); @@ -20,12 +21,16 @@ fn filled_area_chart() { let mut plot = Plot::new(); plot.add_trace(trace1); plot.add_trace(trace2); - println!("{}", plot.to_json()); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: filled_area_chart -fn vertical_and_horizontal_lines_positioned_relative_to_axes() { +// ANCHOR: vertical_and_horizontal_lines_positioned_relative_to_axes +fn vertical_and_horizontal_lines_positioned_relative_to_axes(show: bool) -> Plot { let trace = Scatter::new(vec![2.0, 3.5, 6.0], vec![1.0, 1.5, 1.0]) .text_array(vec![ "Vertical Line", @@ -83,10 +88,15 @@ fn vertical_and_horizontal_lines_positioned_relative_to_axes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: vertical_and_horizontal_lines_positioned_relative_to_axes -fn lines_positioned_relative_to_the_plot_and_to_the_axes() { +// ANCHOR: lines_positioned_relative_to_the_plot_and_to_the_axes +fn lines_positioned_relative_to_the_plot_and_to_the_axes(show: bool) -> Plot { let trace = Scatter::new(vec![2.0, 6.0], vec![1.0, 1.0]) .text_array(vec![ "Line positioned relative to the plot", @@ -126,10 +136,15 @@ fn lines_positioned_relative_to_the_plot_and_to_the_axes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: lines_positioned_relative_to_the_plot_and_to_the_axes -fn creating_tangent_lines_with_shapes() { +// ANCHOR: creating_tangent_lines_with_shapes +fn creating_tangent_lines_with_shapes(show: bool) -> Plot { let x0 = Array::linspace(1.0, 3.0, 200).into_raw_vec_and_offset().0; let y0 = x0.iter().map(|v| *v * (v.powf(2.)).sin() + 1.).collect(); @@ -181,10 +196,15 @@ fn creating_tangent_lines_with_shapes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: creating_tangent_lines_with_shapes -fn rectangles_positioned_relative_to_the_axes() { +// ANCHOR: rectangles_positioned_relative_to_the_axes +fn rectangles_positioned_relative_to_the_axes(show: bool) -> Plot { let trace = Scatter::new(vec![1.5, 4.5], vec![0.75, 0.75]) .text_array(vec!["Unfilled Rectangle", "Filled Rectangle"]) .mode(Mode::Text); @@ -222,10 +242,15 @@ fn rectangles_positioned_relative_to_the_axes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: rectangles_positioned_relative_to_the_axes -fn rectangle_positioned_relative_to_the_plot_and_to_the_axes() { +// ANCHOR: rectangle_positioned_relative_to_the_plot_and_to_the_axes +fn rectangle_positioned_relative_to_the_plot_and_to_the_axes(show: bool) -> Plot { let trace = Scatter::new(vec![1.5, 3.], vec![2.5, 2.5]) .text_array(vec![ "Rectangle reference to the plot", @@ -268,10 +293,15 @@ fn rectangle_positioned_relative_to_the_plot_and_to_the_axes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: rectangle_positioned_relative_to_the_plot_and_to_the_axes -fn highlighting_time_series_regions_with_rectangle_shapes() { +// ANCHOR: highlighting_time_series_regions_with_rectangle_shapes +fn highlighting_time_series_regions_with_rectangle_shapes(show: bool) -> Plot { let x = vec![ "2015-02-01", "2015-02-02", @@ -345,10 +375,15 @@ fn highlighting_time_series_regions_with_rectangle_shapes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: highlighting_time_series_regions_with_rectangle_shapes -fn circles_positioned_relative_to_the_axes() { +// ANCHOR: circles_positioned_relative_to_the_axes +fn circles_positioned_relative_to_the_axes(show: bool) -> Plot { let trace = Scatter::new(vec![1.5, 3.5], vec![0.75, 2.5]) .text_array(vec!["Unfilled Circle", "Filled Circle"]) .mode(Mode::Text); @@ -389,10 +424,15 @@ fn circles_positioned_relative_to_the_axes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: circles_positioned_relative_to_the_axes -fn highlighting_clusters_of_scatter_points_with_circle_shapes() { +// ANCHOR: highlighting_clusters_of_scatter_points_with_circle_shapes +fn highlighting_clusters_of_scatter_points_with_circle_shapes(show: bool) -> Plot { let mut rng = thread_rng(); let x0 = Normal::new(2., 0.45) .unwrap() @@ -501,10 +541,15 @@ fn highlighting_clusters_of_scatter_points_with_circle_shapes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: highlighting_clusters_of_scatter_points_with_circle_shapes -fn venn_diagram_with_circle_shapes() { +// ANCHOR: venn_diagram_with_circle_shapes +fn venn_diagram_with_circle_shapes(show: bool) -> Plot { let mut plot = Plot::new(); plot.add_trace( Scatter::new(vec![1., 1.75, 2.5], vec![1., 1., 1.]) @@ -567,10 +612,15 @@ fn venn_diagram_with_circle_shapes() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: venn_diagram_with_circle_shapes -fn adding_shapes_to_subplots() { +// ANCHOR: adding_shapes_to_subplots +fn adding_shapes_to_subplots(show: bool) -> Plot { let mut plot = Plot::new(); plot.add_trace( Scatter::new(vec![2, 6], vec![1, 1]) @@ -653,10 +703,15 @@ fn adding_shapes_to_subplots() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot } +// ANCHOR_END: adding_shapes_to_subplots -fn svg_paths() { +// ANCHOR: svg_paths +fn svg_paths(show: bool) -> Plot { let mut plot = Plot::new(); plot.add_trace( Scatter::new(vec![2, 1, 8, 8], vec![0.25, 9., 2., 6.]) @@ -711,22 +766,62 @@ fn svg_paths() { plot.set_layout(layout); - plot.show(); + if show { + plot.show(); + } + plot +} +// ANCHOR_END: svg_paths + +fn write_example_to_html(plot: Plot, name: &str) { + std::fs::create_dir_all("./out").unwrap(); + let html = plot.to_inline_html(Some(name)); + std::fs::write(format!("./out/{}.html", name), html).unwrap(); } fn main() { - // Uncomment any of these lines to display the example. - - filled_area_chart(); - // vertical_and_horizontal_lines_positioned_relative_to_axes(); - // lines_positioned_relative_to_the_plot_and_to_the_axes(); - // creating_tangent_lines_with_shapes(); - // rectangles_positioned_relative_to_the_axes(); - // rectangle_positioned_relative_to_the_plot_and_to_the_axes(); - // highlighting_time_series_regions_with_rectangle_shapes(); - // circles_positioned_relative_to_the_axes(); - // highlighting_clusters_of_scatter_points_with_circle_shapes(); - // venn_diagram_with_circle_shapes(); - // adding_shapes_to_subplots(); - // svg_paths(); + // Change false to true on any of these lines to display the example. + + write_example_to_html(filled_area_chart(false), "filled_area_chart"); + write_example_to_html( + vertical_and_horizontal_lines_positioned_relative_to_axes(false), + "vertical_and_horizontal_lines_positioned_relative_to_axes", + ); + write_example_to_html( + lines_positioned_relative_to_the_plot_and_to_the_axes(false), + "lines_positioned_relative_to_the_plot_and_to_the_axes", + ); + write_example_to_html( + creating_tangent_lines_with_shapes(false), + "creating_tangent_lines_with_shapes", + ); + write_example_to_html( + rectangles_positioned_relative_to_the_axes(false), + "rectangles_positioned_relative_to_the_axes", + ); + write_example_to_html( + rectangle_positioned_relative_to_the_plot_and_to_the_axes(false), + "rectangle_positioned_relative_to_the_plot_and_to_the_axes", + ); + write_example_to_html( + highlighting_time_series_regions_with_rectangle_shapes(false), + "highlighting_time_series_regions_with_rectangle_shapes", + ); + write_example_to_html( + circles_positioned_relative_to_the_axes(false), + "circles_positioned_relative_to_the_axes", + ); + write_example_to_html( + highlighting_clusters_of_scatter_points_with_circle_shapes(false), + "highlighting_clusters_of_scatter_points_with_circle_shapes", + ); + write_example_to_html( + venn_diagram_with_circle_shapes(false), + "venn_diagram_with_circle_shapes", + ); + write_example_to_html( + adding_shapes_to_subplots(false), + "adding_shapes_to_subplots", + ); + write_example_to_html(svg_paths(false), "svg_paths"); }