ruviz
High-performance 2D plotting library for Rust combining matplotlib's ease-of-use with Makie's performance.
Release Notes
Quick Start
use *;
let x: = .map.collect;
let y: = x.iter.map.collect;
new
.line
.title
.xlabel
.ylabel
.save?;
Need typeset math labels? See Typst Text Mode below.

Features
🛡️ Safety & Quality
- Zero unsafe in public API
- Strong type system prevents runtime errors
- Comprehensive error handling with
Resulttypes - Memory-safe by design
📊 Plot Types
Basic: Line, Scatter, Bar, Histogram, Box Plot, Heatmap Distribution: Violin, KDE, ECDF Composition: Pie, Donut Continuous: Contour Polar: Polar Plot, Radar Chart Error: Error Bars (symmetric/asymmetric)
🎨 Publication Quality
- High-DPI export: 72, 96, 300, 600 DPI for print
- Multiple formats: PNG, SVG, and PDF (with the
pdffeature) - Professional themes: Light, Dark, Publication, Seaborn-style
- Custom styling: Colors, fonts, markers, line styles
- International text: Full UTF-8 support (Japanese, Chinese, Korean, etc.) with cosmic-text
⚡ Advanced Features
- Simple API: One-liner functions for quick plotting
- Parallel rendering: Multi-threaded for large datasets (rayon)
- GPU acceleration: Optional wgpu backend (experimental)
- Interactive plots: Optional winit window integration
- Animation: GIF export with
record!macro and easing functions - Cross-platform: Linux, macOS, Windows
Installation
Add to your Cargo.toml:
[]
= "0.1.5"
Feature Flags
Choose features based on your needs:
[]
= { = "0.1.5", = ["parallel", "simd"] }
| Feature | Description | Use When |
|---|---|---|
default |
ndarray + parallel | General use |
parallel |
Multi-threaded rendering | Large datasets |
simd |
Vectorized transforms | Performance-critical |
animation |
GIF animation export | Animated plots |
gpu |
GPU acceleration backend (experimental) | Opt-in GPU rendering |
interactive |
winit window support | Interactive plots |
ndarray_support |
ndarray types | Scientific computing |
nalgebra_support |
nalgebra vectors/matrices | Linear algebra workloads |
polars_support |
DataFrame support | Data analysis |
pdf |
PDF export | Publication output |
typst-math |
Typst text engine for all plot text | Math-heavy publication plots |
full |
Most bundled features (excludes HQ GIF/video extras) | Power users |
For minimal builds: default-features = false
Typst Text Mode
Enable Typst text rendering:
[]
= { = "0.1.5", = ["typst-math"] }
Use .typst(true) on a plot to render all static text surfaces (titles, axis labels, ticks,
legend labels, and annotations) through Typst:
use *;
let x: = .map.collect;
let y: = x.iter.map.collect;
new
.line
.title
.xlabel
.ylabel
.typst
.save?;
Notes:
- Invalid Typst snippets fail render/export with a
TypstError. - If
typst-mathis not enabled,.typst(true)returnsFeatureNotEnabledat render/export. - Migration:
.latex(true)has been removed; use.typst(true)instead. - Typst text in PNG output is rasterized at native output scale (1x).
- For maximum text sharpness, prefer higher DPI (for example
.dpi(300)) or vector export (.export_svg(...)/.save_pdf(...)). - DPI changes output density, not the intended physical size of fonts, strokes, markers, or layout spacing.
- Prefer
.size(width_in, height_in)when you care about physical figure size..size_px(width, height)is a convenience that maps pixels through the 100-DPI reference size before final output DPI is applied. - Ticks are enabled by default and render inward on all four sides. Use
.ticks(false)to hide tick marks and tick labels while keeping the frame and axis titles. - Migration: if you want the older bottom/left-only tick appearance, call
.ticks_bottom_left(). - Migration: if you previously relied on high-DPI exports making lines, markers, or text look larger, set those sizes explicitly instead of relying on DPI.
Tick customization:
use *;
new
.line
.tick_direction_inout
.ticks_bottom_left
.show_top_ticks
.show_right_ticks
.save?;
Examples
Basic Line Plot
use *;
let x = vec!;
let y = vec!;
new
.line
.title
.save?;
Multi-Series with Styling
use *;
let x = vec!;
new
.line
.label
.line
.label
.line
.label
.title
.xlabel
.ylabel
.theme
.save?;
Grouped Series with Shared Styling
use *;
let x = vec!;
let a = vec!;
let b = vec!;
let baseline = vec!;
new
.group
.line
.label
.legend
.save?;
Subplots
use *;
let plot1 = new.line.title.end_series;
let plot2 = new.scatter.title.end_series;
let plot3 = new.bar.title.end_series;
let data = vec!;
let plot4 = new
.histogram
.title
.end_series;
subplots?
.suptitle
.subplot?
.subplot?
.subplot?
.subplot?
.save?;
Large Dataset
use *;
// 100,000-point PNG export
let x: = .map.collect;
let y: = x.iter.map.collect;
new
.line
.title
.save?;
Animation
Enable the animation feature for this example:
[]
= { = "0.1.5", = ["animation"] }
use *;
use RecordConfig;
use record;
let x: = .map.collect;
let config = new.max_resolution.framerate;
record!?;

Typst Text Example
Run:
Documentation
- User Guide - Comprehensive tutorials and examples
- API Documentation - Complete API reference
- Gallery - Visual examples showcase
- Migration from matplotlib - For Python users
- Migration from seaborn - Statistical plots
- Performance Guide - Optimization techniques
Why ruviz?
Rust's plotting ecosystem has several options, but each has trade-offs:
| Library | Approach | Limitation |
|---|---|---|
| plotters | Low-level drawing API | Verbose, requires boilerplate for common plots |
| plotly.rs | JavaScript bindings | Requires JS runtime, web-focused |
| plotpy | Python/matplotlib wrapper | Requires Python installed |
ruviz fills the gap with:
- High-level API: matplotlib-style
Plot::new().line().title().save()- no boilerplate - Pure Rust: No Python, JavaScript, or external runtime needed
- Built-in plot types: 15+ plot types out of the box (violin, KDE, radar, etc.)
- Publication quality: Professional themes and high-DPI export
// plotters: ~30 lines for a simple line plot
// ruviz: 4 lines
new
.line
.title
.save?;
Contributing
Contributions welcome! See CONTRIBUTING.md for setup, testing, and pull request guidelines.
Development
# Clone repository
# Setup pre-commit hooks (recommended)
# Run code quality checks
# Run tests
# Run examples
# Run benchmarks
The pre-commit hooks will automatically run cargo fmt --check and cargo clippy before each commit to ensure code quality.
Roadmap
- Core plot types (line, scatter, bar, histogram, boxplot, heatmap)
- Parallel rendering
- SIMD optimization
- GPU acceleration (experimental)
- Professional themes
- Subplots and multi-panel figures
- Distribution plots: Violin, KDE, ECDF
- Composition plots: Pie, Donut
- Continuous plots: Contour
- Polar plots: Polar, Radar
- Error bars
- SVG export
- Experimental interactive window support
- High-level APIs for area, hexbin, step, and stem plots
- High-level APIs for regression and composite plots
- Stabilize the interactive zoom/pan workflow
- 3D plotting (v1.0+)
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.
Acknowledgments
- Inspired by matplotlib, seaborn, and Makie.jl
- Built with tiny-skia for rendering
- Text rendering by cosmic-text
- Thanks to the Rust community for excellent crates and feedback
Status: v0.1.5 - Early development, API may change. Production use at your own risk.
Support: Open an issue or start a discussion