ruviz
High-performance 2D plotting library for Rust.
Visual Examples
Click any plot to open its runnable Rust source. See the complete gallery for more plot types, themes, publication layouts, and international text examples.
| Line plot | Scatter plot | Heatmap |
|---|---|---|
![]() |
![]() |
![]() |
| Violin plot | Radar chart | Multi-panel figure |
|---|---|---|
![]() |
![]() |
![]() |
Quick Start
Add the crate:
[]
= "0.6.0"
Create and save a PNG:
use *;
Run with:

Common API
The main API is the fluent Plot builder. Series are finalized automatically when
you render, save, or start another series.
use *;
Every plot is built the same way — Plot::new(), a series method, setters,
save. There is no second entry point to learn:
use *;
The top-level line/scatter/bar functions and the ruviz::simple module are
deprecated in favour of that chain; see
docs/migration/0.6-builder-api.md.
Plot Types
The root Plot builder exposes 29 plot types, and that list is complete:
- Basic: line, scatter, bar, histogram, box plot, heatmap
- Distribution: KDE, ECDF, violin, boxen, rug
- Categorical: strip, swarm, grouped bar, stacked bar
- Composition and polar: pie, donut styling, radar, polar line
- Continuous, discrete, and error plots: contour, area, stacked area, fill between, hexbin, step, stem, symmetric/asymmetric error bars
- Hierarchical: dendrogram
- Vector: quiver
- Layout helpers: subplots, legends, grid/tick controls, annotations, insets
With the 3d feature, Plot3D adds four more: 3D scatter, 3D line, surface
and wireframe.
All of them except fill_between are series methods that take the same shape —
Plot::new(), a series method, setters, a terminal call — so
.<series>(..).label(..).color(..).legend_best().save(..) compiles for every one
of them. fill_between is an annotation rather than a series: it returns the
plot itself, so it takes plot-level setters (.title(..), .xlabel(..)) rather
than series-level ones.
Grouped bar, stacked bar and stacked area take N named value columns over one
shared axis — .grouped_bar(&categories, &[("Q1", &q1), ("Q2", &q2)]) — and
push one ordinary series per column, so each column gets its own palette colour,
its own legend entry, and the same .color()/.label() rules as a line.
Joint plots and pair plots are figures, not series: plots::composite::{jointplot, pairplot} return a SubplotFigure, the same type subplots returns, so they are
composed with .suptitle(..).save(..) rather than with the series chain.
Anything not in that list has no builder method and cannot be drawn with that
chain, even though the source tree contains implementations of it. Specifically,
2D KDE, regression plot and residual plot have no Plot builder, and Sankey
diagrams and streamplots are not implemented at all.
The ruviz::plots module docs list
which is which, and a test keeps that list in step with the builder.
Export
save("plot.png")writes PNG files on native targets.render()returns an in-memoryImage.render_png_bytes()returns PNG bytes.export_svg("plot.svg")writes SVG files on native targets.render_to_svg()returns an SVG string.save_pdf("plot.pdf")is available with thepdffeature.
For browser/wasm targets, use in-memory helpers such as render_png_bytes(),
render_to_svg(), and Image::encode_png() instead of native file-path export
helpers.
Feature Flags
Default features are ndarray_support and parallel.
| Feature | Description |
|---|---|
3d |
Plot3D: 3D scatter, line, surface and wireframe |
ndarray_support |
ndarray data support (canonical) |
ndarray |
compatibility alias for ndarray_support |
polars_support |
polars data support (canonical) |
polars |
compatibility alias for polars_support |
nalgebra_support |
nalgebra data support (canonical) |
nalgebra |
compatibility alias for nalgebra_support |
parallel |
multi-threaded tile rasterization for the software 3D backend |
simd |
SIMD support used by performance-oriented paths |
performance |
shorthand for parallel + simd |
gpu |
enables GPU types and .gpu(true) metadata |
interactive |
standalone interactive window support (canonical) |
window |
compatibility alias for interactive |
interactive-gpu |
interactive + gpu |
serde |
serialize themes/configuration types |
pdf |
PDF export via SVG-to-PDF |
typst-math |
Typst-backed text rendering |
animation |
GIF recording support |
animation-video |
animation + AV1 video encoding |
svg |
no-op, retained for compatibility (see below) |
full |
broad feature set for native builds |
SVG export is always compiled in: render_to_svg() and export_svg() need no
feature flag, and the svg feature gates nothing.
parallel is enabled by default because the software 3D rasterizer renders its
tiles across a rayon pool. It does not currently affect the 2D raster path,
and the crate's own measurements put it between 0.94x and 1.05x on 2D workloads
— see docs/benchmarks/rust-feature-impact.md.
Measure your own workload before turning on performance.
Backend Notes
.backend(...), .auto_optimize(), and .get_backend_name() store or report
backend preference metadata. auto_optimize() conservatively selects Skia rather
than advertising a backend that cannot execute across every public raster path.
Use .resolved_backend_name() for the native Plot PNG path, or
.backend_resolution(...) to inspect the requested backend, actual backend, and
any explicit Skia fallback reason for a raster operation. Supported scatter
workloads resolve to DataShader only when that backend is explicitly configured.
Use release builds and benchmark your actual workload before adding optional performance features. See Backend Selection and Performance Optimization.
Native GUI Integration
Ruviz provides image-backed adapters for the major native Rust GUI frameworks.
Each adapter supports static and interactive 2D plots, and forwards the 3d,
gpu, and 3d-gpu feature surfaces without selecting an application shell:
| Framework | Crate and guide |
|---|---|
| egui | ruviz-egui |
| Iced | ruviz-iced |
| Slint | ruviz-slint |
| GPUI | ruviz-gpui |
The adapters retain the last successful image while rendering newer requests
in the background. GPU presentation remains image-backed: 3d-gpu renders on
the GPU and reads the completed frame back for the GUI framework to upload.
Typst Text Mode
Enable Typst-backed text rendering with:
[]
= { = "0.6.0", = ["typst-math"] }
Then call .typst(true). The configured family is passed to plain raster,
plain SVG, and Typst text. Named-font consistency depends on that font being
available to each renderer or SVG viewer; otherwise backend-specific fallback
or substitution may occur. Typst resolves serif, sans-serif, and monospace
to available concrete families. Because Typst has no generic cursive or fantasy
selector, those two values use its selected sans-serif fallback:
use *;
Without typst-math, .typst(true) and TextEngineMode::Typst are not
compiled. If Typst is optional in your crate, forward and guard your own feature:
[]
= { = "0.6.0", = false }
[]
= []
= ["ruviz/typst-math"]
use *;
Examples
Rust documentation examples are in examples/doc_*.rs.
Interactive examples require the interactive feature:
Animation examples require the animation feature:
Documentation
Development
The workspace also contains companion crates and bindings, but this README focuses on the root Rust crate. See the subdirectory READMEs for those package surfaces.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE or http://opensource.org/licenses/MIT)
at your option.





