Shapes

The following imports have been used to produce the plots below:

#![allow(unused)]
fn main() {
use itertools_num::linspace;
use plotly::common::{
    Fill, Font, Mode,
};
use plotly::layout::{
    Axis, GridPattern, Layout, LayoutGrid, Margin, Shape, ShapeLayer, ShapeLine,
    ShapeType,
};
use plotly::{Bar, color::NamedColor, Plot, Scatter};
use rand::thread_rng;
use rand_distr::{Distribution, Normal};
}

The to_inline_html method is used to produce the html plot displayed in this page.

Filled Area Chart

#![allow(unused)]
fn main() {
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")));
}
}

Vertical and Horizontal Lines Positioned Relative to Axes

#![allow(unused)]
fn main() {
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"
        ))
    );
}
}

Lines Positioned Relative to the Plot and to the Axes

#![allow(unused)]
fn main() {
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"
        ))
    );
}
}

Creating Tangent Lines with Shapes

#![allow(unused)]
fn main() {
fn creating_tangent_lines_with_shapes(show: bool) {
    let x0: Vec<f64> = linspace(1.0, 3.0, 200).collect();
    let y0: Vec<f64> = 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"))
    );
}
}

Rectangles Positioned Relative to the Axes

#![allow(unused)]
fn main() {
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"))
    );
}
}

Rectangle Positioned Relative to the Plot and to the Axes

#![allow(unused)]
fn main() {
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"
        ))
    );
}
}

Highlighting Time Series Regions with Rectangle Shapes

#![allow(unused)]
fn main() {
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"
        ))
    );
}
}

Circles Positioned Relative to the Axes

#![allow(unused)]
fn main() {
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"))
    );
}
}

Highlighting Clusters of Scatter Points with Circle Shapes

#![allow(unused)]
fn main() {
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::<Vec<f64>>();
    let y0 = Normal::new(2., 0.45)
        .unwrap()
        .sample_iter(rng)
        .take(300)
        .collect::<Vec<f64>>();
    let x1 = Normal::new(6., 0.4)
        .unwrap()
        .sample_iter(rng)
        .take(300)
        .collect::<Vec<f64>>();
    let y1 = Normal::new(6., 0.4)
        .unwrap()
        .sample_iter(rng)
        .take(300)
        .collect::<Vec<f64>>();
    let x2 = Normal::new(4., 0.3)
        .unwrap()
        .sample_iter(rng)
        .take(300)
        .collect::<Vec<f64>>();
    let y2 = Normal::new(4., 0.3)
        .unwrap()
        .sample_iter(rng)
        .take(300)
        .collect::<Vec<f64>>();

    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"
        ))
    );
}
}

Venn Diagram with Circle Shapes

#![allow(unused)]
fn main() {
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"))
    );
}
}

Adding Shapes to Subplots

#![allow(unused)]
fn main() {
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")));
}
}

SVG Paths

#![allow(unused)]
fn main() {
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")));
}
}