Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- [[#414](https://github.com/plotly/plotly.rs/issues/414)] Add `DensityMap` (MapLibre `map` subplot) trace type — density heatmaps with full color-scale and hover support
- [[#417](https://github.com/plotly/plotly.rs/issues/417)] Add `ScatterMap` (MapLibre `map` subplot) trace type — the modern counterpart to `ScatterMapbox`
- [[#418](https://github.com/plotly/plotly.rs/issues/418)] Add native point clustering to `ScatterMap` via a `Cluster` option
- [[#421](https://github.com/plotly/plotly.rs/pull/421)] Backfill trace attributes on trace types to bring them to parity with plotly.js 3.7
- [[#421](https://github.com/plotly/plotly.rs/pull/421)] Backfill trace attributes for trace types to bring them to parity with plotly.js 3.7
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Add `Indicator`, `Histogram2d`, `Icicle` trace types
- [[#425](https://github.com/plotly/plotly.rs/issues/425)] Add `Splom` and `Parcats` trace types (scatter-plot matrix and parallel categories)

### Changed

Expand Down
2 changes: 2 additions & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Bar Charts](./recipes/basic_charts/bar_charts.md)
- [Pie Charts](./recipes/basic_charts/pie_charts.md)
- [Sankey Diagrams](./recipes/basic_charts/sankey_diagrams.md)
- [Parallel Categories](./recipes/basic_charts/parcats_charts.md)
- [Treemap Charts](./recipes/basic_charts/treemap_charts.md)
- [Sunburst Charts](./recipes/basic_charts/sunburst_charts.md)
- [Icicle Charts](./recipes/basic_charts/icicle_charts.md)
Expand All @@ -26,6 +27,7 @@
- [Violin Plots](./recipes/statistical_charts/violin_plots.md)
- [Histograms](./recipes/statistical_charts/histograms.md)
- [2D Histograms](./recipes/statistical_charts/histogram2d.md)
- [SPLOM](./recipes/statistical_charts/splom.md)
- [Scientific Charts](./recipes/scientific_charts.md)
- [Contour Plots](./recipes/scientific_charts/contour_plots.md)
- [Heatmaps](./recipes/scientific_charts/heatmaps.md)
Expand Down
9 changes: 5 additions & 4 deletions docs/book/src/recipes/basic_charts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Line Charts | [![Line Charts](./img/line_shape_options_for_interpolation.png)](.
Bar Charts | [![Bar Charts](./img/bar_chart_with_error_bars.png)](./basic_charts/scatter_plots.md)
Pie Charts | [![Pie Charts](./img/pie_charts.png)](./basic_charts/pie_charts.md)
Sankey Diagrams | [![Sankey Diagrams](./img/basic_sankey.png)](./basic_charts/sankey_diagrams.md)
Treemap Charts | [Treemap Charts](./basic_charts/treemap_charts.md)
Sunburst Charts | [Sunburst Charts](./basic_charts/sunburst_charts.md)
Icicle Charts | [Icicle Charts](./basic_charts/icicle_charts.md)
Indicator Charts | [Indicator Charts](./basic_charts/indicator_charts.md)
Parallel Categories | [![Parallel Categories](./img/parallelcat.png)](./basic_charts/parcats_charts.md)
Treemap Charts | [![Treemap Charts](./img/treemap.png)](./basic_charts/treemap_charts.md)
Sunburst Charts | [![Sunburst Charts](./img/sunburst.png)](./basic_charts/sunburst_charts.md)
Icicle Charts | [![Icicle Charts](./img/icicle.png)](./basic_charts/icicle_charts.md)
Indicator Charts | [![Indicator Charts](./img/indicator.png)](./basic_charts/indicator_charts.md)
38 changes: 38 additions & 0 deletions docs/book/src/recipes/basic_charts/parcats_charts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Parallel Categories

A parallel categories (`parcats`) chart visualizes multi-dimensional categorical
data as a set of parallel axes, one per category column, with ribbons flowing
between the categories. Like Sankey diagrams, it is domain-based rather than
cartesian — each [`ParcatsDimension`](https://docs.rs/plotly/latest/plotly/parcats/struct.ParcatsDimension.html)
defines one axis, and optional `counts` let you weight aggregated paths instead
of plotting one row per observation.

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

```rust,no_run
use plotly::color::NamedColor;
use plotly::common::Domain;
use plotly::layout::Layout;
use plotly::parcats::{
ParcatsArrangement, ParcatsDimension, ParcatsHoverInfo, ParcatsHoverOn, ParcatsLine,
ParcatsLineShape,
};
use plotly::{Parcats, Plot};
```

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

## Basic Parallel Categories
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:basic_parcats}}
```

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


## Styled Parallel Categories
```rust,no_run
{{#include ../../../../../examples/basic_charts/src/main.rs:styled_parcats}}
```

{{#include ../../../../../examples/basic_charts/output/inline_styled_parcats.html}}
Binary file added docs/book/src/recipes/img/icicle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/book/src/recipes/img/indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/book/src/recipes/img/parallelcat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/book/src/recipes/img/splom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/book/src/recipes/img/sunburst.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/book/src/recipes/img/treemap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/book/src/recipes/statistical_charts.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Box Plots | [![Line Charts](./img/box_plot.png)](./statistical_charts/box_plots.
Violin Plots | [![Violin Plots](./img/violin_plot.png)](./statistical_charts/violin_plots.md)
Histograms | [![Scatter Plots](./img/overlaid_histogram.png)](./statistical_charts/histograms.md)
2D Histograms | [![2D Histograms](./img/basic_histogram2d.png)](./statistical_charts/histogram2d.md)
SPLOM | [![SPLOM](./img/splom.png)](./statistical_charts/splom.md)
34 changes: 34 additions & 0 deletions docs/book/src/recipes/statistical_charts/splom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPLOM

A SPLOM (scatter plot matrix) visualizes multivariate data as a grid of scatter
subplots — one cell for each pair of dimensions. Each column of your dataset
becomes a [`SplomDimension`](https://docs.rs/plotly/latest/plotly/splom/struct.SplomDimension.html),
and Plotly.js lays out the axis grid automatically, so you do not assign explicit
`xaxis`/`yaxis` ids as you would for cartesian traces.

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

```rust,no_run
use plotly::color::NamedColor;
use plotly::common::Marker;
use plotly::layout::Layout;
use plotly::splom::{SplomDiagonal, SplomDimension};
use plotly::{Plot, Splom};
```

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

## Basic SPLOM
```rust,no_run
{{#include ../../../../../examples/statistical_charts/src/main.rs:basic_splom}}
```

{{#include ../../../../../examples/statistical_charts/output/inline_basic_splom.html}}


## Styled SPLOM
```rust,no_run
{{#include ../../../../../examples/statistical_charts/src/main.rs:styled_splom}}
```

{{#include ../../../../../examples/statistical_charts/output/inline_styled_splom.html}}
81 changes: 80 additions & 1 deletion examples/basic_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ use plotly::{
LayoutPolar, Legend, PolarAxisAttributes, PolarAxisTicks, PolarDirection, RadialAxis,
TicksDirection, TraceOrder,
},
parcats::{
ParcatsArrangement, ParcatsDimension, ParcatsHoverInfo, ParcatsHoverOn, ParcatsLine,
ParcatsLineShape,
},
sankey::{Line as SankeyLine, Link, Node},
sunburst::{InsideTextOrientation, Leaf},
traces::indicator::{
Expand All @@ -26,7 +30,8 @@ use plotly::{
Align as TableAlign, Cells, Fill as TableFill, Font as TableFont, Header, Line as TableLine,
},
treemap::{BranchValues, Marker as TreemapMarker, Packing, PathBar, Side, Tiling},
Bar, Icicle, Indicator, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst, Table, Treemap,
Bar, Icicle, Indicator, Parcats, Pie, Plot, Sankey, Scatter, ScatterPolar, Sunburst, Table,
Treemap,
};
use plotly_utils::write_example_to_html;
use rand_distr::{Distribution, Normal, Uniform};
Expand Down Expand Up @@ -887,6 +892,76 @@ fn custom_node_sankey_diagram(show: bool, file_name: &str) {
}
// ANCHOR_END: custom_node_sankey_diagram

// Parallel Categories
// ANCHOR: basic_parcats
fn basic_parcats(show: bool, file_name: &str) {
let trace = Parcats::new()
.name("survey responses")
.dimensions(vec![
ParcatsDimension::new()
.label("Region")
.values(vec!["North", "South", "North", "East", "West", "South"]),
ParcatsDimension::new()
.label("Product")
.values(vec!["A", "B", "A", "C", "B", "A"]),
ParcatsDimension::new().label("Channel").values(vec![
"Online", "Retail", "Online", "Retail", "Online", "Retail",
]),
])
.arrangement(ParcatsArrangement::Perpendicular);

let layout = Layout::new().title("Basic Parallel Categories");
let mut plot = Plot::new();
plot.set_layout(layout);
plot.add_trace(trace);

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

// ANCHOR: styled_parcats
fn styled_parcats(show: bool, file_name: &str) {
let trace = Parcats::new()
.name("passengers")
.dimensions(vec![
ParcatsDimension::new()
.label("Sex")
.values(vec!["M", "F", "F", "M", "F", "M"]),
ParcatsDimension::new()
.label("Class")
.values(vec!["First", "Second", "Third", "Third", "First", "Second"]),
ParcatsDimension::new()
.label("Survived")
.values(vec!["yes", "no", "yes", "no", "yes", "no"]),
])
.counts_array(vec![1.0, 2.0, 1.0, 3.0, 1.0, 2.0])
.line(
ParcatsLine::new()
.color(NamedColor::SteelBlue)
.shape(ParcatsLineShape::Hspline)
.show_scale(true),
)
.arrangement(ParcatsArrangement::Perpendicular)
.bundle_colors(true)
.hover_on(ParcatsHoverOn::Category)
.hover_info(ParcatsHoverInfo::CountAndProbability)
.domain(Domain::new());

let layout = Layout::new().title("Styled Parallel Categories");
let mut plot = Plot::new();
plot.set_layout(layout);
plot.add_trace(trace);

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

// ANCHOR: table_chart
fn table_chart(show: bool, file_name: &str) {
let trace = Table::new(
Expand Down Expand Up @@ -1436,6 +1511,10 @@ fn main() {
basic_sankey_diagram(false, "basic_sankey_diagram");
custom_node_sankey_diagram(false, "custom_node_sankey_diagram");

// Parallel Categories
basic_parcats(false, "basic_parcats");
styled_parcats(false, "styled_parcats");

// Pie Charts
basic_pie_chart(false, "basic_pie_chart");
basic_pie_chart_labels(false, "basic_pie_chart_labels");
Expand Down
119 changes: 118 additions & 1 deletion examples/statistical_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use plotly::{
},
histogram::{Bins, Cumulative, HistFunc, HistNorm},
layout::{Axis, BarMode, BoxMode, Layout, Margin, ViolinMode},
splom::{SplomDiagonal, SplomDimension},
violin::{MeanLine, ViolinBox, ViolinPoints, ViolinSide},
Bar, BoxPlot, Histogram, Histogram2d, Plot, Scatter, Violin,
Bar, BoxPlot, Histogram, Histogram2d, Plot, Scatter, Splom, Violin,
};
use plotly_utils::write_example_to_html;
use rand_distr::{Distribution, Normal, Uniform};
Expand Down Expand Up @@ -868,6 +869,118 @@ fn histogram2d_aggregation(show: bool, file_name: &str) {
}
// ANCHOR_END: histogram2d_aggregation

// SPLOM
fn splom_axis() -> Axis {
Axis::new()
.show_line(false)
.zero_line(false)
.grid_color("#ffffff")
.tick_length(4)
}

fn splom_layout(title: &str, dimensions: usize) -> Layout {
let axis = splom_axis;
let mut layout = Layout::new()
.title(title)
.height(800)
.width(800)
.auto_size(false)
.x_axis(axis())
.y_axis(axis());

if dimensions >= 2 {
layout = layout.x_axis2(axis()).y_axis2(axis());
}
if dimensions >= 3 {
layout = layout.x_axis3(axis()).y_axis3(axis());
}
if dimensions >= 4 {
layout = layout.x_axis4(axis()).y_axis4(axis());
}
if dimensions >= 5 {
layout = layout.x_axis5(axis()).y_axis5(axis());
}
if dimensions >= 6 {
layout = layout.x_axis6(axis()).y_axis6(axis());
}
if dimensions >= 7 {
layout = layout.x_axis7(axis()).y_axis7(axis());
}
if dimensions >= 8 {
layout = layout.x_axis8(axis()).y_axis8(axis());
}

layout
}

// ANCHOR: basic_splom
fn basic_splom(show: bool, file_name: &str) {
let n = 200;
let sepal_length = sample_normal_distribution(n, 5.8, 0.8);
let sepal_width = sample_normal_distribution(n, 3.0, 0.4);
let petal_length = sample_normal_distribution(n, 3.8, 1.8);
let petal_width = sample_normal_distribution(n, 1.2, 0.8);

let trace = Splom::new().name("flower measurements").dimensions(vec![
SplomDimension::new()
.label("Sepal Length")
.values(sepal_length),
SplomDimension::new()
.label("Sepal Width")
.values(sepal_width),
SplomDimension::new()
.label("Petal Length")
.values(petal_length),
SplomDimension::new()
.label("Petal Width")
.values(petal_width),
]);

let mut plot = Plot::new();
plot.set_layout(splom_layout("Flower Measurements", 4));
plot.add_trace(trace);

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

// ANCHOR: styled_splom
fn styled_splom(show: bool, file_name: &str) {
let n = 150;
let x = sample_uniform_distribution(n, 0.0, 10.0);
let y = sample_uniform_distribution(n, 0.0, 10.0);
let z = sample_normal_distribution(n, 5.0, 2.0);

let trace = Splom::new()
.name("styled splom")
.dimensions(vec![
SplomDimension::new().label("X").values(x),
SplomDimension::new().label("Y").values(y),
SplomDimension::new().label("Z").values(z),
])
.diagonal(SplomDiagonal::new().visible(false))
.show_upper_half(false)
.marker(
Marker::new()
.size(4)
.opacity(0.6)
.color(NamedColor::SteelBlue),
);

let mut plot = Plot::new();
plot.set_layout(splom_layout("Styled SPLOM", 3));
plot.add_trace(trace);

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

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

Expand Down Expand Up @@ -925,4 +1038,8 @@ fn main() {
basic_histogram2d(false, "basic_histogram2d");
styled_histogram2d(false, "styled_histogram2d");
histogram2d_aggregation(false, "histogram2d_aggregation");

// SPLOM
basic_splom(false, "basic_splom");
styled_splom(false, "styled_splom");
}
2 changes: 2 additions & 0 deletions plotly/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ pub enum PlotType {
Indicator,
Mesh3D,
Ohlc,
Parcats,
Sankey,
Splom,
Surface,
DensityMapbox,
DensityMap,
Expand Down
10 changes: 5 additions & 5 deletions plotly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ pub use plot::{Plot, Trace, Traces};
// Also provide easy access to modules which contain additional trace-specific types
pub use traces::{
box_plot, choropleth, choropleth_map, contour, density_map, heat_map, histogram, histogram2d,
icicle, image, indicator, mesh3d, sankey, scatter, scatter3d, scatter_map, scatter_mapbox,
sunburst, surface, treemap, violin,
icicle, image, indicator, mesh3d, parcats, sankey, scatter, scatter3d, scatter_map,
scatter_mapbox, splom, sunburst, surface, treemap, violin,
};
// Bring the different trace types into the top-level scope
pub use traces::{
Bar, BoxPlot, Candlestick, Choropleth, ChoroplethMap, Contour, DensityMap, DensityMapbox,
HeatMap, Histogram, Histogram2d, Icicle, Image, Indicator, Mesh3D, Ohlc, Pie, Sankey, Scatter,
Scatter3D, ScatterGeo, ScatterMap, ScatterMapbox, ScatterPolar, Sunburst, Surface, Table,
Treemap, Violin,
HeatMap, Histogram, Histogram2d, Icicle, Image, Indicator, Mesh3D, Ohlc, Parcats, Pie, Sankey,
Scatter, Scatter3D, ScatterGeo, ScatterMap, ScatterMapbox, ScatterPolar, Splom, Sunburst,
Surface, Table, Treemap, Violin,
};

pub trait Restyle: serde::Serialize {}
Expand Down
Loading
Loading