Skip to main content

ruviz

Rust-powered plotting for Python. ruviz wraps the ruviz rendering engine in a fluent, fully typed Python API: build a plot by chaining method calls, then export it to PNG, SVG, or PDF, display it in a Jupyter cell, drive it live from an observable, or open it in a native desktop window. NumPy arrays cross into Rust with a single memcpy and rendering runs with the GIL released, so million-point series stay interactive.

Install

pip install ruviz

The base install pulls in NumPy only. Everything else is an extra:

Extra Install Adds
pip install ruviz Static PNG/SVG/PDF export, native show(), static notebook display
widget pip install "ruviz[widget]" anywidget + traitlets for plot.widget() and RuvizWidget
pandas pip install "ruviz[pandas]" pandas DataFrame columns through data=
polars pip install "ruviz[polars]" Polars DataFrame columns through data=
dataframes pip install "ruviz[dataframes]" Both dataframe backends
all pip install "ruviz[all]" Every extra

import ruviz works without any extra; plot.widget() and ruviz.RuvizWidget raise an ImportError that names ruviz[widget] when the extra is missing.

Quick Start

import numpy as np
import ruviz

x = np.linspace(0.5, 12.0, 60)
fast = 8.0 * np.exp(-x * 0.62)
slow = 6.0 * np.exp(-x * 0.22)

(
    ruviz.plot()
    .size_px(760, 420)
    .title("Decay Rates")
    .xlabel("time")
    .ylabel("intensity")
    .line(x, fast, label="fast decay", color="#2563eb", width=2.0)
    .line(x, slow, label="slow decay", color="orange", linestyle="dashed")
    .yscale("log")
    .grid(True)
    .legend("upper_right")
    .save("decay.png")
)

Features

  • 15 plot types — line, scatter, bar, histogram, boxplot, violin, kde, ecdf, error bars (y and xy), heatmap, contour, pie, radar, polar line.
  • Per-series styling — labels, colors, alpha, widths, line styles, markers, plus kind-specific bins, bandwidth, and levels.
  • Axis controllegend(), grid(), xlim/ylim, and linear, log, or symlog scales.
  • Static exportsave() writes PNG, SVG, or PDF; render_png() returns bytes and render_svg() returns a string.
  • Jupyter — plots display as a static PNG by default; plot.widget() gives you the synced, zoomable WASM widget with the ruviz[widget] extra.
  • Live dataruviz.observable(...) series support elementwise arithmetic and NumPy ufuncs, and push updates into attached widgets.
  • DataFrames — pandas, Polars, plain dicts, and anything else indexable by column name through data=.
  • Experimental 3D alpha — deterministic static export for scatter3d, line3d, surface, and wireframe.
  • Typed — inline annotations with a py.typed marker, so a type checker rejects a bad marker=, linestyle=, legend position, or axis scale before the call reaches the renderer.
  • Fast — adding a 1,000,000-point line series takes about 1 ms (it was 141 ms before the arrays were passed as a single memcpy), and rendering, saving, and native display all release the GIL.

Styling

Series style arguments are keyword-only, and each kind accepts exactly what the renderer honors for it:

method keywords
line label, color, alpha, width, linestyle, marker, marker_size
scatter label, color, alpha, marker, marker_size
bar label, color, alpha
histogram label, color, alpha, bins
boxplot label, color, alpha, width, linestyle
kde label, color, alpha, width, bandwidth
ecdf, violin, polar_line, error_bars, error_bars_xy label, color, alpha, width
contour alpha, width, levels

heatmap, pie, and radar take no style keywords.

  • color takes a hex string ("#2563eb", "#25f", "#2563eb80") or a named color such as "red", "orange", "teal", or "crimson"; a typo raises ValueError with a "did you mean" suggestion.
  • linestyle is one of solid, dashed, dotted, dash-dot, dash-dot-dot.
  • marker is one of circle, square, triangle, triangle-down, diamond, plus, cross, star, circle-open, square-open, triangle-open, diamond-open.
  • The matplotlib shorthands are accepted as aliases — "o", "s", "^", "v", "D", "+", "x", "*" for marker and "-", "--", ":", "-." for linestyle — and snapshots store the canonical name.
  • Unsupported names raise ValueError listing the accepted values at the call that used them, not at render time.

Plot-level settings are legend(position="best")"best" plus lowercase position names such as "upper_right", "center", or "outside_right"grid(enabled=True), dpi(dpi), xlim(min, max), ylim(min, max), and xscale(scale, linthresh=None) / yscale(...) with "linear", "log", or "symlog". dpi scales the exported pixels from size_px(...), so size_px(640, 480).dpi(200) writes a 1280×960 image. Axis limits must be finite and different; passing them inverted, as in xlim(10, 0), renders a descending axis (Plot3D limits stay strictly ascending).

Notebook widgets render these settings too: the WASM runtime applies series styles, dpi, legend, grid, axis limits, and axis scales from the snapshot.

Notebook and Desktop Usage

  • In Jupyter, a bare plot result and plot.show() both display a static PNG.
  • Use plot.widget() when you want the synced WASM-backed notebook widget.
  • plot.size_px(width, height) also controls the widget's displayed size and aspect ratio.
  • Without size_px(...), the widget uses the default PNG size (640x480) and shrinks proportionally if the notebook column is narrower.
  • Drag the widget's bottom-right handle to resize the display freely; hold Shift or Ctrl while dragging to preserve the aspect ratio.
  • In the widget, the mouse wheel zooms, left drag pans, right drag box-zooms, and right click opens the export menu.
  • Outside notebooks, plot.show() opens the native interactive window.
  • The published Linux wheel focuses on static rendering and notebook widgets. Install from source on Linux if you need the native desktop plot.show() window.
  • plot.render_png() returns PNG bytes and plot.render_svg() returns an SVG string.
  • plot.save(path) writes PNG, SVG, or PDF according to the file extension and returns the output Path; any other extension, or a path without one, raises ValueError.

Reactive Notebook Data

Use ruviz.observable(...) for notebook-driven updates that keep explicit widgets in sync:

import numpy as np
import ruviz

x = np.linspace(0.0, 6.0, 200)
y = ruviz.observable(np.sin(x))

plot = ruviz.plot().size_px(640, 360).line(x, y).title("Live Sine Wave")
widget = plot.widget()

ObservableSeries supports elementwise arithmetic and NumPy ufuncs. Derived observables stay live until you write to them directly. Live observable series are supported by line, scatter, bar, histogram, boxplot, error_bars, and error_bars_xy; other plot types reject them with a TypeError and expect static values.

import numpy as np

scaled = np.sin(y * 2.0 + 0.25)
plot.line(x, scaled)
y.replace(np.cos(x))

replace() is atomic: when the new length would break a bound series — directly or through a derived observable — it raises ValueError before anything mutates. Derived observables resize along with their source, so a plot of x against np.sin(x) stays consistent when x grows, and writing to an observable with replace() or set_at() permanently detaches it from its own sources. len(series) and series[i] read the current values. deepcopy(plot) creates an independent live copy with fresh observables, while plot.clone() remains a static snapshot copy.

Experimental 3D Alpha

The Python wheel includes the Rust crate's opt-in Cargo feature named exactly 3d. The initial Python surface provides deterministic CPU export for opaque scatter3d, line3d, regular-grid surface, and wireframe plots:

import numpy as np
import ruviz

x = np.linspace(-2.0, 2.0, 32)
y = np.linspace(-2.0, 2.0, 24)
grid_x, grid_y = np.meshgrid(x, y)
z = np.sin(grid_x**2 + grid_y**2)

(
    ruviz.surface(x, y, z)
    .size_px(720, 480)
    .title("3D surface alpha")
    .xlabel("x")
    .ylabel("y")
    .zlabel("z")
    .save("surface.png")
)

For surfaces and wireframes, rows of z correspond to y and columns correspond to x, so z.shape == (len(y), len(x)). Orthographic projection is the default; .perspective_deg(45.0) opts into perspective. This alpha is static-only in Python: interactive orbit widgets, transparency, volume plots, arbitrary meshes, and mixed 2D/3D axes are not yet exposed.

Supported Python Versions and Platforms

  • Python 3.10 or newer. Wheels are built as a single abi3 artifact per platform and are tested against 3.10 and 3.13.
  • Wheels: macOS x86_64 and arm64, Windows x86_64, Linux x86_64 and aarch64 (manylinux 2_28). A source distribution is published as well.
  • The Linux wheels are built without the native interactive backend, so plot.show() raises there and asks you to install from source.

Documentation

Contributor Workflow

cd bindings/python
uv sync
uv run maturin develop
uv run python scripts/generate_gallery.py
uv run mkdocs serve

Rebuild the bundled widget frontend from the repository root when you change the web SDK or packages/ruviz/src/python-widget.ts:

bun run build:python-widget

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ruviz-0.7.0.tar.gz (6.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ruviz-0.7.0-cp310-abi3-win_amd64.whl (7.6 MB view details)

Uploaded CPython 3.10+Windows x86-64

ruviz-0.7.0-cp310-abi3-manylinux_2_28_x86_64.whl (7.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

ruviz-0.7.0-cp310-abi3-manylinux_2_28_aarch64.whl (7.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

ruviz-0.7.0-cp310-abi3-macosx_11_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

ruviz-0.7.0-cp310-abi3-macosx_10_12_x86_64.whl (7.8 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file ruviz-0.7.0.tar.gz.

File metadata

  • Download URL: ruviz-0.7.0.tar.gz
  • Upload date:
  • Size: 6.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ruviz-0.7.0.tar.gz
Algorithm Hash digest
SHA256 9d21a05801a59e891a5ec19327e239d7819ed782930529f50ed81dc83cb45ff4
MD5 d129de5fd12f5b26e5a6589f042d7480
BLAKE2b-256 46ac725c6ccc7922eedc3701728d4bfee7b9390b2f8d51419a65a6a59c182e42

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0.tar.gz:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ruviz-0.7.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: ruviz-0.7.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 7.6 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ruviz-0.7.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 6631befa28ab58e0b6a07d9335a99e26034ffe35bdb155347254492829097fe4
MD5 101def8c6a927fb9c25ac6228145541a
BLAKE2b-256 03c87c3d9fb03f766277009b8dc6aed50cb16fddc8eee77173f435d8cc489ac2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ruviz-0.7.0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ruviz-0.7.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b83d0362d69e61954b1f70dbedf0199ac05ee8fbbf2c841ab90c139c0dfb0f9e
MD5 c8cee6a735c4f523a4d21af1f06eaf39
BLAKE2b-256 c470c0536b6b29124102f106a21c3f7eefe1405f11485a4c5a4e3155bb79f813

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0-cp310-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ruviz-0.7.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ruviz-0.7.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a21e04142f1aa1fc097c5fbf77b42ed9601a18a1a7c5d899945473fcd95c41c2
MD5 519b36dd6ac8597714738c8d20c333a5
BLAKE2b-256 df194e545cf4429245364345079f4fe01e24b093c1357f1a925de7514d28e7d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ruviz-0.7.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ruviz-0.7.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cd423f605e2711f1ef612e071d51f6475f5c8b3977c76ace16812b2712711982
MD5 c9fa3336dd504376a33b27476a9899d2
BLAKE2b-256 f189a084e098d5a8cf2c08d02fc1cb4a70a18f4dcdea4ad76d6d9a57c4511de7

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ruviz-0.7.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ruviz-0.7.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0d7824f102977e3c96bc292be6a9f2e3eaa74fe1e588a9b32ae3e0d01b4975af
MD5 36de15d04c36e44b6d7a11196d11ac56
BLAKE2b-256 b79c4cb98359e94352e2c5ad43f1ff46f3a358baf8018dff3f8840aa5b5584fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for ruviz-0.7.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on Ameyanagi/ruviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page