Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
03a5dc4
Remove deprecated kaleido backend and EPS image format
jqnatividad Oct 17, 2026
f1d5d06
Bump dependencies and drop unused zip build-dependency
jqnatividad Oct 17, 2026
5d68616
Release 0.15.0
jqnatividad Oct 17, 2026
16b30fb
ci: let cargo-semver-checks infer the release type
jqnatividad Oct 17, 2026
48b387b
examples: fix off-by-one in sinusoidal slider traces
jqnatividad Oct 17, 2026
ea7c2bf
style: apply rustfmt from nightly 2026-10-16
jqnatividad Oct 17, 2026
a21da1f
Fix pedantic doc/lazy-static lints and add_frames duplication
jqnatividad Oct 17, 2026
7a4a297
feat(traces): add BarPolar and FunnelArea trace types (#422)
jqnatividad Oct 18, 2026
4479979
feat(traces): add Cone, StreamTube, IsoSurface and Volume traces (#422)
jqnatividad Oct 18, 2026
9abed12
feat(traces): add Parcoords trace type (#422)
jqnatividad Oct 18, 2026
00fde49
feat(traces): add ScatterTernary and ScatterSmith with their subplots…
jqnatividad Oct 18, 2026
7dec22b
feat(traces): add Carpet, ScatterCarpet and ContourCarpet traces (#422)
jqnatividad Oct 18, 2026
0f87192
docs(changelog): update 0.15.0 section for full trace coverage
jqnatividad Oct 18, 2026
b7ab67c
fix: address review findings on the new trace types (#422)
jqnatividad Oct 18, 2026
55555b2
feat(traces): add Histogram2dContour trace type (#422)
jqnatividad Oct 18, 2026
43a4ee4
fix(layout): omit unset polar and geo-rotation fields instead of writ…
jqnatividad Oct 18, 2026
3223bd7
fix(themes): style polar and ternary subplots in plotly_dark
jqnatividad Oct 18, 2026
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
14 changes: 6 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
# lint the main library workspace for non-wasm target
- run: cargo clippy --features all -- -D warnings -A deprecated
# lint the non-wasm examples
- run: cd ${{ github.workspace }}/examples && cargo clippy --workspace --exclude "wasm*" --exclude "kaleido" -- -D warnings
- run: cd ${{ github.workspace }}/examples && cargo clippy --workspace --exclude "wasm*" -- -D warnings
# lint the plotly library for wasm target
- run: cargo clippy --package plotly --target wasm32-unknown-unknown -- -D warnings
# lint the wasm examples
Expand All @@ -67,9 +67,8 @@ jobs:
with:
package: plotly
feature-group: only-explicit-features
features: kaleido
features: static_export_chromedriver
rust-toolchain: stable
release-type: minor

test:
name: Tests
Expand Down Expand Up @@ -135,7 +134,7 @@ jobs:
# Run tests on Ubuntu with Chrome
- name: Run tests (${{ matrix.os }} - Chrome)
if: matrix.os == 'ubuntu-latest' && matrix.browser == 'chrome'
run: cargo test --workspace --features ${{ matrix.features }} --exclude plotly_kaleido
run: cargo test --workspace --features ${{ matrix.features }}

# Install xvfb for Firefox WebGL support
- name: Install xvfb
Expand All @@ -157,12 +156,12 @@ jobs:
echo "BROWSER_PATH: $BROWSER_PATH"
echo "RUST_LOG: $RUST_LOG"

xvfb-run -s "-screen 0 1920x1080x24" cargo test --workspace --features ${{ matrix.features }} --exclude plotly_kaleido
xvfb-run -s "-screen 0 1920x1080x24" cargo test --workspace --features ${{ matrix.features }}

# Run tests on macOS with Chrome
- name: Run tests (${{ matrix.os }} - Chrome)
if: matrix.os == 'macos-latest' && matrix.browser == 'chrome'
run: cargo test --workspace --features ${{ matrix.features }} --exclude plotly_kaleido
run: cargo test --workspace --features ${{ matrix.features }}

# Run tests on Windows with Chrome WebDriver
- name: Run tests (${{ matrix.os }} - Chrome)
Expand All @@ -180,7 +179,7 @@ jobs:
Write-Host "WEBDRIVER_PATH: $env:WEBDRIVER_PATH"
Write-Host "BROWSER_PATH: $env:BROWSER_PATH"

cargo test --workspace --features ${{ matrix.features }} --exclude plotly_kaleido
cargo test --workspace --features ${{ matrix.features }}

- name: Upload static image(s) artifact
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -218,7 +217,6 @@ jobs:
customization/multiple_plots_example,
financial_charts,
images,
kaleido,
maps,
ndarray,
scientific_charts,
Expand Down
16 changes: 0 additions & 16 deletions .github/workflows/publish_plotly_kaleido.yml

This file was deleted.

2 changes: 0 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ jobs:
install-chromedriver: true
- run: cargo publish --allow-dirty -p plotly_derive
- run: sleep 10
- run: cargo publish --allow-dirty -p plotly_kaleido
- run: sleep 10
- run: cargo publish --allow-dirty -p plotly
# plotly_static is not part of the same ecosystem yet so it doesn't use the same TOKEN
# - run: sleep 10
Expand Down
33 changes: 31 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

## [0.15.0] - 2026-10-18

This is the last release bundling plotly.js 3.x; the upgrade to plotly.js 4.x is planned for 0.16.0 ([#437](https://github.com/plotly/plotly.rs/issues/437)).

Highlights: plotly.rs now exposes every non-deprecated plotly.js 3.7 trace type ([#422](https://github.com/plotly/plotly.rs/issues/422)) — 27 trace types are new since 0.14.1 — adds the MapLibre `map`, ternary and Smith chart subplots, and drops the deprecated Kaleido backend. Breaking changes are marked **Breaking** below.

### Added

- [[#406](https://github.com/plotly/plotly.rs/issues/406)] Expose `plotly.js` 3.1–3.6 attributes
Expand All @@ -13,19 +19,42 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- [[#412](https://github.com/plotly/plotly.rs/pull/412)] Add `Violin` trace type with box, mean line, KDE span, and split/grouped support
- [[#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`
- Add `Funnel` trace type (bar-like, cartesian) with `Connector` and `FunnelHoverInfo` options, plus the layout-level `funnelmode`/`funnelgap`/`funnelgroupgap` attributes and a `FunnelMode` enum
- Add `Waterfall` trace type (bar-like, cartesian) with a typed `Measure` enum (`absolute`/`relative`/`total`), per-class `increasing`/`decreasing`/`totals` styling via `MeasureStyle`, a `Connector` with `ConnectorMode`, and a `WaterfallHoverInfo` enum. The layout-level `waterfallmode`/`waterfallgap`/`waterfallgroupgap` attributes and the `WaterfallMode` enum already existed
- [[#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 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)
- [[#432](https://github.com/plotly/plotly.rs/issues/432)] Add `Funnel` and `Waterfall` trace types
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Complete trace-type coverage for plotly.js 3.7: add `BarPolar`, `FunnelArea`, `Cone`, `StreamTube`, `IsoSurface`, `Volume`, `Parcoords`, `ScatterTernary`, `ScatterSmith`, `Carpet`, `ScatterCarpet`, `ContourCarpet` and `Histogram2dContour` (which previously had a `PlotType` variant but no trace to emit it). Every non-deprecated plotly.js 3.7 trace type is now exposed. The new traces omit Chart Studio `*src` attributes, which plotly.js 4 removes
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Add the ternary and Smith chart subplots (`LayoutTernary`/`TernaryAxis`, `LayoutSmith`/`RealAxis`/`ImaginaryAxis`), polar-subplot `bar_mode`/`bar_gap` (`PolarBarMode`) for `BarPolar`, the `funnelareacolorway`/`extendfunnelareacolors`/`hiddenlabels` layout attributes, and `ThetaUnit::Gradians` (breaking for exhaustive matches on `ThetaUnit`)
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Examples and mdBook recipe pages for every new trace type: polar bar, parallel coordinates, funnel area, vector field (cone/streamtube), isosurface/volume, ternary, Smith and carpet charts, and 2D histogram contours

### Changed

- [[#406](https://github.com/plotly/plotly.rs/issues/406)] Upgrade bundled plotly.js from 3.0.1 to 3.6.0
- [[#419](https://github.com/plotly/plotly.rs/issues/419)] Upgrade bundled plotly.js from 3.6.0 to 3.7.0
- [[#422](https://github.com/plotly/plotly.rs/issues/422)] Add layout-level `uirevision` to preserve UI state (zoom/pan/selection) across re-renders (complements the trace-level `uirevision` added in #421)
- `plotly_static` bumped to 0.2.0 (breaking: `ImageFormat::EPS` removed)
- Bump `darling` to 0.24 and `syn` to 3 in `plotly_derive`, and `dirs` to 7 in `plotly_static`
- Bump example dependencies: `reqwest` 0.13, `env_logger` 0.11, `itertools` 0.15, `ndarray` 0.17, `rand`/`rand_chacha` 0.10
- Theme statics in `plotly::layout::themes` (`DEFAULT`, `PLOTLY_WHITE`, `PLOTLY_DARK`, …) are now `std::sync::LazyLock<Template>` instead of `once_cell::sync::Lazy<Template>`; the `once_cell` dependency is dropped. Code that only dereferences them is unaffected
- Add `# Errors`/`# Panics` sections to public fallible APIs and tidy doc formatting (clippy `missing_errors_doc`, `missing_panics_doc`, `doc_markdown`)
- **Breaking**: `mesh3d::LightPosition` fields `x`/`y`/`z` are now `f64` instead of `Vec<f64>`. plotly.js expects a single number per coordinate and silently ignored the arrays, so `Mesh3D` light positions never took effect. Replace e.g. `.x(vec![10.0])` with `.x(10.0)`. `LightPosition` and `Lighting` are now also used by the new `Cone`, `StreamTube`, `IsoSurface` and `Volume` traces

### Removed

- The deprecated Kaleido static export backend: the `plotly_kaleido` crate is no longer part of the workspace, and the `kaleido` and `kaleido_download` features are gone. Use the `static_export_*` features (`plotly_static`) instead
- The deprecated `ImageFormat::EPS` variant. Use `ImageFormat::SVG` or `ImageFormat::PDF` for vector output

### Fixed

- `Plot::add_frames` no longer adds every frame twice when the plot has no frames yet
- `LayoutPolar`, its axes, `PolarTickMode` and the geo `Rotation` no longer serialize unset fields as `null`, so the JSON carries only the attributes that were set
- The `plotly_dark` template now styles polar and ternary subplots (dark background, grid and axis lines, matching plotly.py's `plotly_dark`); polar and ternary charts drew a white background on it

### Security

- Remove the unused `zip` build-dependency from `plotly_static`; with `plotly_kaleido` gone, no workspace crate depends on `zip` directly
- Known issue: `zip` 8.x is still pulled in transitively by `webdriver-downloader` 0.17 (used at build time to fetch chromedriver/geckodriver) and is flagged by RUSTSEC-2026-0367/0368/0369. Those advisories concern `ZipArchive::extract()`, which `webdriver-downloader` does not call (it reads the driver entry with `by_name`). It will be resolved once [ik1ne/webdriver-downloader#67](https://github.com/ik1ne/webdriver-downloader/pull/67) is released

## [0.14.1] - 2026-02-15

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
resolver = "2"
members = ["plotly", "plotly_derive", "plotly_kaleido", "plotly_static"]
members = ["plotly", "plotly_derive", "plotly_static"]
63 changes: 5 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
* [Basic Usage](#basic-usage)
* [Exporting a single Interactive Plot](#exporting-a-single-interactive-plot)
* [Exporting Static Images with plotly_static (Recommended)](#exporting-static-images-with-plotly_static-recommended)
* [Exporting Static Images with Kaleido (legacy)](#exporting-static-images-with-kaleido-legacy)
* [Usage Within a WASM Environment](#usage-within-a-wasm-environment)
* [Timeseries Downsampling](#timeseries-downsampling)
* [Crate Feature Flags](#crate-feature-flags)
Expand All @@ -63,7 +62,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
plotly = "0.14"
plotly = "0.15"
```

## Exporting a single Interactive Plot
Expand Down Expand Up @@ -103,7 +102,7 @@ The recommended way to export static images is using the `plotly_static` backend

```toml
[dependencies]
plotly = { version = "0.14", features = ["static_export_default"] }
plotly = { version = "0.15", features = ["static_export_default"] }
```

This supports PNG, JPEG, WEBP, SVG, and PDF formats:
Expand All @@ -122,56 +121,15 @@ let svg_string = plot.to_svg(800, 600, 1.0)?;

**Note:** This feature requires a WebDriver-compatible browser (Chrome or Firefox) as well as a Webdriver (chromedriver/geckodriver) to be available on the system.

The above example uses the legacy API that is backwards compatible with the Kaleido API. However, for more efficient workflows a `StaticExporter` object can be built and reused between calls to `write_image`.
The above example uses the one-shot `Plot` API, which creates a new exporter for every call. However, for more efficient workflows a `StaticExporter` object can be built and reused between calls to `write_image`.

More specifically, enabling any of the `plotly` features `static_export_chromedriver`, `static_export_geckodriver`, or `static_export_default` gives access to both the synchronous `StaticExporter` and the asynchronous `AsyncStaticExporter` (available via `plotly::plotly_static`). For exporter reuse and up-to-date sync/async usage patterns, please see the dedicated example in `examples/static_export`, which demonstrates both synchronous and asynchronous exporters and how to reuse a single exporter instance across multiple exports.

For further details see [`plotly_static` crate documentation](https://docs.rs/plotly_static/).

## Exporting Static Images with Kaleido (legacy)

Enable the `kaleido` feature and opt in for automatic downloading of the `kaleido` binaries by doing the following

```toml
# Cargo.toml

[dependencies]
plotly = { version = "0.14", features = ["kaleido", "kaleido_download"] }
```

Alternatively, enable only the `kaleido` feature and manually install Kaleido.
```toml
# Cargo.toml

[dependencies]
plotly = { version = "0.14", features = ["kaleido"] }
```

With the feature enabled, plots can be saved as any of `png`, `jpeg`, `webp`, `svg`, `pdf` and `eps`. Note that the plot will be a static image, i.e. they will be non-interactive.

Exporting a simple plot looks like this:

```rust
use plotly::{ImageFormat, Plot};

let mut plot = Plot::new();
let trace = Scatter::new(vec![0, 1, 2], vec![2, 1, 0]);
plot.add_trace(trace);

plot.write_image("out.png", ImageFormat::PNG, 800, 600, 1.0);
```

### Kaleido external dependency

When developing applications for your host, enabling both `kaleido` and `kaleido_download` features will ensure that the `kaleido` binary is downloaded for your system's architecture at compile time. After download, it is unpacked into a specific path, e.g., on Linux this is `/home/USERNAME/.config/kaleido`. With these two features enabled, static images can be exported as described in the next section as long as the application runs on the same machine where it has been compiled on.

When the applications developed with `plotly.rs` are intended for other targets or when the user wants to control where the `kaleido` binary is installed then Kaleido must be manually downloaded and installed. Setting the environment variable `KALEIDO_PATH=/path/installed/kaleido/` will ensure that applications that were built with the `kaleido` feature enabled can locate the `kaleido` executable and use it to generate static images.

Kaleido binaries are available on Github [release page](https://github.com/plotly/Kaleido/releases). It currently supports Linux(`x86_64`), Windows(`x86_64`) and MacOS(`x86_64`/`aarch64`).

## Usage Within a WASM Environment

`Plotly.rs` can be used with a WASM-based frontend framework. Note that the `kaleido` and `plotly_static` static export features are not supported in WASM environments and will throw a compilation error if used.
`Plotly.rs` can be used with a WASM-based frontend framework. Note that the `plotly_static` static export features are not supported in WASM environments and will throw a compilation error if used.

The needed dependencies are automatically enabled for `wasm32` targets at compile time and there is no longer a need for the custom `wasm` flag in this crate.

Expand All @@ -184,7 +142,7 @@ First, make sure that you have the Plotly JavaScript library in your base HTML t
<html lang="en">
<head>
<!-- snip -->
<script src="https://cdn.plot.ly/plotly-2.14.0.min.js"></script>
<script src="https://cdn.plot.ly/plotly-3.7.0.min.js"></script>
</head>
<!-- snip -->
</html>
Expand Down Expand Up @@ -263,17 +221,6 @@ When the feature is enabled, users can still opt in for the CDN version by using

Note that when using `Plot::to_inline_html()`, it is assumed that the `plotly.js` library is already in scope within the HTML file, so enabling this feature flag will have no effect.

### `kaleido` (legacy)

Adds plot save functionality to the following formats: `png`, `jpeg`, `webp`, `svg`, `pdf` and `eps`.

Requires `Kaleido` to have been previously installed on the host machine. See the following feature flag and [Kaleido external dependency](#kaleido-external-dependency).

### `kaleido_download` (legacy)

Enable download and install of Kaleido binary at build time from [Kaleido releases](https://github.com/plotly/Kaleido/releases/) on the host machine.
See [Kaleido external dependency](#kaleido-external-dependency) for more details.

# Contributing

* If you've spotted a bug or would like to see a new feature, please submit an issue on the [issue tracker](https://github.com/plotly/plotly.rs/issues).
Expand Down
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doc-valid-idents = ["WebDriver", "MapLibre", "GeoJSON", "MathJax", "ModeBar", ".."]
7 changes: 7 additions & 0 deletions docs/book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
- [Icicle Charts](./recipes/basic_charts/icicle_charts.md)
- [Sankey Diagrams](./recipes/basic_charts/sankey_diagrams.md)
- [Parallel Categories](./recipes/basic_charts/parcats_charts.md)
- [Parallel Coordinates](./recipes/basic_charts/parcoords_charts.md)
- [Polar Bar Charts](./recipes/basic_charts/polar_bar_charts.md)
- [Indicator Charts](./recipes/basic_charts/indicator_charts.md)
- [Statistical Charts](./recipes/statistical_charts.md)
- [Error Bars](./recipes/statistical_charts/error_bars.md)
Expand All @@ -32,6 +34,9 @@
- [Scientific Charts](./recipes/scientific_charts.md)
- [Contour Plots](./recipes/scientific_charts/contour_plots.md)
- [Heatmaps](./recipes/scientific_charts/heatmaps.md)
- [Ternary Plots](./recipes/scientific_charts/ternary_plots.md)
- [Smith Charts](./recipes/scientific_charts/smith_charts.md)
- [Carpet Plots](./recipes/scientific_charts/carpet_plots.md)
- [Financial Charts](./recipes/financial_charts.md)
- [Time Series and Date Axes](./recipes/financial_charts/time_series_and_date_axes.md)
- [Candlestick Charts](./recipes/financial_charts/candlestick_charts.md)
Expand All @@ -43,6 +48,8 @@
- [Scatter 3D](./recipes/3dcharts/3dcharts.md)
- [Surface Plots](./recipes/3dcharts/surface_plots.md)
- [Mesh3D](./recipes/3dcharts/mesh3d_plots.md)
- [Vector Field Plots](./recipes/3dcharts/vector_field_plots.md)
- [Isosurface and Volume Plots](./recipes/3dcharts/volume_plots.md)
- [Maps](./recipes/maps.md)
- [Scatter Maps](./recipes/maps/scatter_maps.md)
- [Density Maps](./recipes/maps/density_maps.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/book/src/fundamentals/jupyter_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ display a plot:

**Cell 1**
```
:dep plotly = "0.14"
:dep plotly = "0.15"
```

**Cell 2**
Expand Down
9 changes: 3 additions & 6 deletions docs/book/src/fundamentals/static_image_export.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ The static export functionality is controlled by feature flags in the main `plot
```toml
# Basic usage with manual Chromedriver installation
[dependencies]
plotly = { version = "0.14", features = ["static_export_chromedriver"] }
plotly = { version = "0.15", features = ["static_export_chromedriver"] }

# With automatic Chromedriver download
[dependencies]
plotly = { version = "0.14", features = ["static_export_chromedriver", "static_export_wd_download"] }
plotly = { version = "0.15", features = ["static_export_chromedriver", "static_export_wd_download"] }

# Recommended: Default configuration with Chromedriver + auto-download
[dependencies]
plotly = { version = "0.14", features = ["static_export_default"] }
plotly = { version = "0.15", features = ["static_export_default"] }
```

> Enabling any of the static export features in `plotly` (`static_export_chromedriver`, `static_export_geckodriver`, or `static_export_default`) enables both APIs from `plotly_static`: the sync `StaticExporter` and the async `AsyncStaticExporter` (reachable as `plotly::plotly_static::AsyncStaticExporter`). Prefer the async API inside async code.
Expand Down Expand Up @@ -110,9 +110,6 @@ exporter.close();
- **SVG**: Scalable Vector Graphics
- **PDF**: Portable Document Format

### Deprecated
- **EPS**: Encapsulated PostScript (will be removed in version 0.15.0)

## String Export

For web applications or APIs, you can export to strings:
Expand Down
Loading
Loading