Skip to content
Open
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
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ jobs:
components: clippy
targets: wasm32-unknown-unknown
# lint plotly_static for all features
- run: cargo check -p plotly_static
- run: cargo test -p plotly_static build_without_driver_feature_returns_error
- run: cargo clippy -p plotly_static --features geckodriver,webdriver_download -- -D warnings -A deprecated
- run: cargo clippy -p plotly_static --features chromedriver,webdriver_download -- -D warnings -A deprecated
# lint the main library workspace for non-wasm target
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

### Added

- [[#412](https://github.com/plotly/plotly.rs/pull/412)] Add `Violin` trace type with box, mean line, KDE span, and split/grouped support
- [[#413](https://github.com/plotly/plotly.rs/issues/413)] Add hover (`hovertext`/`hoverinfo`/`hovertemplate`/`customdata`/`hoverlabel`/`text`) and color-scale (`colorscale`/`colorbar`/`showscale`/`reversescale`/`autocolorscale`/`coloraxis`) support, plus `ids`/`meta`/`uirevision`/`below`, to `DensityMapbox`
- [[#406](https://github.com/plotly/plotly.rs/issues/406)] Expose `plotly.js` 3.1–3.6 attributes
- [[#410](https://github.com/plotly/plotly.rs/pull/410)] Add `Choropleth` (geo subplot) and `ChoroplethMap` (MapLibre `map` subplot) trace types, with a `LocationMode` enum and a dedicated `choropleth::Marker`; add the MapLibre `map` subplot via `LayoutMap`/`MapStyle`/`MapBounds`
- [[#410](https://github.com/plotly/plotly.rs/pull/410)] Add `LayoutGeo` options: `fitbounds` (`GeoFitBounds`), `resolution` (`GeoResolution`, 1:110M/1:50M base-layer detail), and `bgcolor`
- [[#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
- Add `ScatterMap` (MapLibre `map` subplot) trace type — the modern counterpart to `ScatterMapbox`, with markers/lines, `Fill`/`Selection`, and full hover support
- Add native point clustering to `ScatterMap` via a `Cluster` option (`enabled`/`color`/`maxzoom`/`opacity`/`size`/`step`) — a `scattermap`-only feature with no `ScatterMapbox` equivalent

### Changed

Expand Down
1 change: 1 addition & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Statistical Charts](./recipes/statistical_charts.md)
- [Error Bars](./recipes/statistical_charts/error_bars.md)
- [Box Plots](./recipes/statistical_charts/box_plots.md)
- [Violin Plots](./recipes/statistical_charts/violin_plots.md)
- [Histograms](./recipes/statistical_charts/histograms.md)
- [Scientific Charts](./recipes/scientific_charts.md)
- [Contour Plots](./recipes/scientific_charts/contour_plots.md)
Expand Down
Binary file added docs/book/src/recipes/img/violin_plot.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 @@ -6,4 +6,5 @@ Kind | Link
:---|:----:
Error Bars |[![Scatter Plots](./img/error_bars.png)](./statistical_charts/error_bars.md)
Box Plots | [![Line Charts](./img/box_plot.png)](./statistical_charts/box_plots.md)
Violin Plots | [![Violin Plots](./img/violin_plot.png)](./statistical_charts/violin_plots.md)
Histograms | [![Scatter Plots](./img/overlaid_histogram.png)](./statistical_charts/histograms.md)
36 changes: 36 additions & 0 deletions docs/book/src/recipes/statistical_charts/violin_plots.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Violin Plots

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

```rust,no_run
use plotly::common::{Line, Orientation};
use plotly::layout::{Layout, ViolinMode};
use plotly::violin::{MeanLine, ViolinBox, ViolinPoints, ViolinSide};
use plotly::{color::NamedColor, Plot, Violin};
```

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


## Basic Violin Plot
```rust,no_run
{{#include ../../../../../examples/statistical_charts/src/main.rs:basic_violin_plot}}
```

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


## Horizontal Violin Plot
```rust,no_run
{{#include ../../../../../examples/statistical_charts/src/main.rs:horizontal_violin_plot}}
```

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


## Split Violin Plot
```rust,no_run
{{#include ../../../../../examples/statistical_charts/src/main.rs:split_violin_plot}}
```

{{#include ../../../../../examples/statistical_charts/output/inline_split_violin_plot.html}}
102 changes: 100 additions & 2 deletions examples/statistical_charts/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use plotly::{
color::{NamedColor, Rgb, Rgba},
common::{ErrorData, ErrorType, Line, Marker, Mode, Orientation},
histogram::{Bins, Cumulative, HistFunc, HistNorm},
layout::{Axis, BarMode, BoxMode, Layout, Margin},
Bar, BoxPlot, Histogram, Plot, Scatter,
layout::{Axis, BarMode, BoxMode, Layout, Margin, ViolinMode},
violin::{MeanLine, ViolinBox, ViolinPoints, ViolinSide},
Bar, BoxPlot, Histogram, Plot, Scatter, Violin,
};
use plotly_utils::write_example_to_html;
use rand_distr::{Distribution, Normal, Uniform};
Expand Down Expand Up @@ -477,6 +478,98 @@ fn fully_styled_box_plot(show: bool, file_name: &str) {
}
// ANCHOR_END: fully_styled_box_plot

// Violin Plots
// ANCHOR: basic_violin_plot
fn basic_violin_plot(show: bool, file_name: &str) {
let y = 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, 0.8, 0.4, 0.6,
];

let trace = Violin::new(y)
.box_plot(ViolinBox::new().visible(true))
.mean_line(MeanLine::new().visible(true))
.name("Total");

let layout = Layout::new().title("Basic Violin Plot");

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_violin_plot

// ANCHOR: horizontal_violin_plot
fn horizontal_violin_plot(show: bool, file_name: &str) {
let x = vec![1.4, 2.1, 1.9, 3.2, 2.7, 2.2, 1.8, 2.5, 3.1, 2.0, 2.6, 1.7];

let trace = Violin::<f64, f64>::default()
.x(x)
.points(ViolinPoints::All)
.box_plot(ViolinBox::new().visible(true))
.mean_line(MeanLine::new().visible(true))
.orientation(Orientation::Horizontal)
.name("Score");

let layout = Layout::new().title("Horizontal Violin Plot");

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: horizontal_violin_plot

// ANCHOR: split_violin_plot
fn split_violin_plot(show: bool, file_name: &str) {
let x = vec![
"Mon", "Mon", "Mon", "Mon", "Tue", "Tue", "Tue", "Tue", "Wed", "Wed", "Wed", "Wed",
];

let trace1 = Violin::new_xy(
x.clone(),
vec![0.6, 0.9, 0.4, 0.7, 0.8, 1.1, 0.6, 0.9, 1.0, 1.3, 0.8, 1.1],
)
.legend_group("Yes")
.scale_group("Yes")
.name("Yes")
.side(ViolinSide::Negative)
.line(Line::new().color(NamedColor::Blue));

let trace2 = Violin::new_xy(
x,
vec![0.4, 0.7, 0.3, 0.5, 0.6, 0.9, 0.4, 0.7, 0.8, 1.1, 0.6, 0.9],
)
.legend_group("No")
.scale_group("No")
.name("No")
.side(ViolinSide::Positive)
.line(Line::new().color(NamedColor::Green));

let layout = Layout::new()
.title("Split Violin Plot")
.violin_mode(ViolinMode::Overlay);

let mut plot = Plot::new();
plot.set_layout(layout);
plot.add_trace(trace1);
plot.add_trace(trace2);

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

// Histograms
fn sample_normal_distribution(n: usize, mean: f64, std_dev: f64) -> Vec<f64> {
let mut rng = rand::rng();
Expand Down Expand Up @@ -729,6 +822,11 @@ fn main() {
grouped_horizontal_box_plot(false, "grouped_horizontal_box_plot");
fully_styled_box_plot(false, "fully_styled_box_plot");

// Violin Plots
basic_violin_plot(false, "basic_violin_plot");
horizontal_violin_plot(false, "horizontal_violin_plot");
split_violin_plot(false, "split_violin_plot");

// Histograms
basic_histogram(false, "basic_histogram");
horizontal_histogram(false, "horizontal_histogram");
Expand Down
1 change: 0 additions & 1 deletion plotly/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,5 @@ image = "0.25"
itertools = ">=0.10, <0.16"
itertools-num = "0.1"
ndarray = "0.17"
plotly_static = { path = "../plotly_static" }
rand_distr = "0.6"
base64 = "0.22"
3 changes: 3 additions & 0 deletions plotly/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ pub enum PlotType {
ScatterGL,
Scatter3D,
ScatterMapbox,
ScatterMap,
ScatterGeo,
ScatterPolar,
ScatterPolarGL,
Expand All @@ -228,12 +229,14 @@ pub enum PlotType {
Sankey,
Surface,
DensityMapbox,
DensityMap,
Table,
Pie,
Treemap,
Sunburst,
Choropleth,
ChoroplethMap,
Violin,
}

#[derive(Serialize, Clone, Debug)]
Expand Down
10 changes: 5 additions & 5 deletions plotly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ pub use layout::Layout;
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, heat_map, histogram, image, mesh3d, sankey,
scatter, scatter3d, scatter_mapbox, sunburst, surface, treemap,
box_plot, choropleth, choropleth_map, contour, density_map, heat_map, histogram, image, mesh3d,
sankey, scatter, scatter3d, scatter_map, scatter_mapbox, sunburst, surface, treemap, violin,
};
// Bring the different trace types into the top-level scope
pub use traces::{
Bar, BoxPlot, Candlestick, Choropleth, ChoroplethMap, Contour, DensityMapbox, HeatMap,
Histogram, Image, Mesh3D, Ohlc, Pie, Sankey, Scatter, Scatter3D, ScatterGeo, ScatterMapbox,
ScatterPolar, Sunburst, Surface, Table, Treemap,
Bar, BoxPlot, Candlestick, Choropleth, ChoroplethMap, Contour, DensityMap, DensityMapbox,
HeatMap, Histogram, Image, Mesh3D, Ohlc, Pie, Sankey, Scatter, Scatter3D, ScatterGeo,
ScatterMap, ScatterMapbox, ScatterPolar, Sunburst, Surface, Table, Treemap, Violin,
};

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