ggrust
The Grammar of Graphics, written in Rust, used from Python.
ggrust is a plotting library with a Lets-Plot compatible Python API. Plots are built the familiar ggplot way, layer by layer with +, while the stats, scales, layout and rendering all run in Rust.
It was started for Cellestial, which needed a maintained backend for its Lets-Plot based API.
Every plot above is ggrust. More in the gallery.
Highlights
- Fast and lean: a median 40x faster SVG, 22x faster PNG and 14x lower peak memory than Lets-Plot on identical work (details).
- ggplot2 extensions, built in: beeswarms, significance brackets, cluster marks, side panels, dendrograms, raincloud plots, patchwork layouts and more, under their R names (list).
- The Lets-Plot API: most code ports with an import swap,
lets_plot->ggrust. - Interactive: notebook and HTML output with tooltips, zoom and pan; dense point layers drawn on a canvas.
- Publication output: SVG, PNG, vector PDF and HTML, with your own fonts. Data crosses into Rust once, as Arrow, so Polars and pandas frames work directly.
Installation
pip install ggrust
uv add ggrust
Quickstart
import polars as pl
from ggrust import *
frame = pl.DataFrame(
{
"height": [150, 162, 171, 180, 168, 175],
"weight": [52, 60, 68, 82, 65, 74],
"group": ["a", "a", "b", "b", "c", "c"],
}
)
plot = (
ggplot(frame, aes(x="height", y="weight", color="group"))
+ geom_point(size=4)
+ labs(title="Height vs weight")
+ ggsize(600, 400)
)
plot.to_png("plot.png")
In a notebook the plot shows as interactive HTML (tooltips, zoom and pan with ggtb()).
ggplot2 extensions, built in
Many popular ggplot2 extension packages from R are built into ggrust, under their R function names. Nothing extra to install; Lets-Plot has none of them.
| Feature | ggrust | From the R package |
|---|---|---|
| Beeswarm and quasirandom points | geom_beeswarm, geom_quasirandom |
ggbeeswarm |
| Journal color palettes | scale_color_npg, _aaas, _nejm, _lancet, _jama, _jco, _d3, _igv |
ggsci |
| Significance tests and labels | stat_compare_means, stat_cor, stat_poly_eq |
ggpubr, ggpmisc |
| Cluster marks | geom_mark_hull, geom_mark_ellipse, geom_mark_rect |
ggforce |
| Highlighting | gghighlight |
gghighlight |
| Point density | geom_pointdensity |
ggpointdensity |
| Side panels | geom_xside*, geom_yside*, ggmarginal |
ggside |
| Several color scales in one plot | new_scale_fill, new_scale_color, new_scale |
ggnewscale |
| Dendrograms | hclust, scale_x_dendro, scale_y_dendro, geom_dendrogram |
legendry, ggh4x, ggdendro |
| Raincloud plots | stat_halfeye, stat_interval, geom_half_violin, geom_half_boxplot, geom_half_point |
ggdist, gghalves |
| Figure layouts and panel tags | gggrid(design=, tag_levels=), inset_element |
patchwork |
| Rasterized layers in vector output | rasterize |
ggrastr, scattermore |
ggrust reimplements their behavior in Rust; the R packages and their authors designed it. Examples and credits are in the extensions guide.
Performance
Compared with Lets-Plot on identical work: same data, every row drawn (Lets-Plot sampling turned off), same output size. Measured on an Apple M4 Pro, ggrust 0.1.0 vs lets-plot 4.11.0.
- Speed: SVG a median 40x faster (5x to 185x over 23 cases), PNG a median 22x faster (13x to 119x).
- Memory: a median 14x lower peak memory (3.6x to 220x). A 1M-point scatter PNG peaks at 44 MB above the data in ggrust and 9.6 GB in Lets-Plot.
- No case was slower. The weakest spots are point-heavy PNGs (13x to 21x) and large SVGs, where ggrust still peaks at 430 MB for 1M points.
Full methodology, raw numbers and side-by-side output images are in the benchmark report.
More examples
Distributions
Violins with boxplots on top, using the same layering as ggplot.
Show code
import numpy as np
rng = np.random.default_rng(0)
days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
commute = pl.DataFrame(
{
"day": np.repeat(days, 200),
"minutes": np.concatenate([rng.gamma(4 + i, 6, 200) for i in range(5)]),
}
)
(
ggplot(commute, aes(x="day", y="minutes", fill="day"))
+ geom_violin(alpha=0.6)
+ geom_boxplot(width=0.15, fill="white")
+ labs(title="Commute time by weekday")
+ theme_classic()
+ ggsize(600, 400)
)
Facets
Split a plot into panels by a column.
Show code
months = np.arange(1, 13)
temperature = pl.DataFrame(
{
"month": np.tile(months, 3),
"temp": np.concatenate(
[10 + 8 * np.sin((months - 3) / 12 * 2 * np.pi) + offset for offset in (0, 5, -4)]
),
"city": np.repeat(["Lisbon", "Athens", "Oslo"], 12),
}
)
(
ggplot(temperature, aes(x="month", y="temp", color="city"))
+ geom_line(size=1.2)
+ geom_point()
+ facet_wrap("city", ncol=3)
+ labs(title="Monthly temperature", y="°C")
+ theme_bw()
+ ggsize(900, 350)
)
What it covers
- Geoms: point, line, path, bar, col, histogram, boxplot, violin, area ridges, tile, raster, rect, text, label, text/label repel, segment, curve, polygon, rug, imshow, brackets and more.
- Stats: count, bin, density, smooth, summary, ecdf, contours, 2D bins, ellipses.
- Scales: continuous, discrete, log, reversed, datetime, hue, manual, gradients, viridis, brewer, secondary axes, axes on any side.
- Layout:
facet_wrap,facet_grid,gggridwith collected legends,coord_fixed,coord_flip, themes (theme_classic,theme_bw,theme_minimal,theme_void, ...). - Outputs: SVG, PNG, vector PDF, and interactive HTML through
ggsave, with your own fonts (register_font). Dense scatter layers are drawn on a canvas in HTML.
ggrust is a subset of Lets-Plot, not all of it. Features follow what Cellestial and everyday plotting need. See the migration note for the differences.
Status
Early, but usable: the full Cellestial test suite passes on ggrust. Expect rough edges and API gaps; issues are welcome.
Development
uv sync # create the dev environment
make develop # build the Rust extension into .venv
make check # fmt, clippy, ruff, cargo test, pytest
Metadata
Release files for ggrust 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ggrust-0.6.1.tar.gz | 2.5 MB | With provenance | Details for ggrust-0.6.1.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| ggrust-0.6.1-cp311-abi3-win_arm64.whl | CPython 3.11 | abi3 | Windows ARM64 | Details for ggrust-0.6.1-cp311-abi3-win_arm64.whl |
| ggrust-0.6.1-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details for ggrust-0.6.1-cp311-abi3-win_amd64.whl |
| ggrust-0.6.1-cp311-abi3-manylinux_2_28_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.28+ x86-64 | Details for ggrust-0.6.1-cp311-abi3-manylinux_2_28_x86_64.whl |
| ggrust-0.6.1-cp311-abi3-manylinux_2_28_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.28+ ARM64 | Details for ggrust-0.6.1-cp311-abi3-manylinux_2_28_aarch64.whl |
| ggrust-0.6.1-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details for ggrust-0.6.1-cp311-abi3-macosx_11_0_arm64.whl |
| ggrust-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details for ggrust-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl |
Total release size: 53.4 MB
Release files / ggrust-0.6.1.tar.gz
| Download URL | ggrust-0.6.1.tar.gz |
|---|---|
| Size | 2.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
507e3019e837313e10ad28301c9bd5624060ff613bd4de368e4dccfb298f78c2
|
|
BLAKE2b-256 checksum How to use checksums |
2a197f0d7016b793b921dd11897f9af5fcab2d54d69fe296046631b82797cfa3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-win_arm64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-win_arm64.whl |
|---|---|
| Size | 8.1 MB |
| Tags | CPython 3.11 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
1c891e6f4dc47daa9f7e516a04a877067ac0f070171509a34d9bb2556c3743bb
|
|
BLAKE2b-256 checksum How to use checksums |
dc0589fd83c0bea78630d16814161f52f272d7583c7b20a506e886fd3e3c2d88
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-win_amd64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 8.8 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e2da22277f7215e7edae77be64bfda846e5c538a93d1b9f2c09b872759849dc5
|
|
BLAKE2b-256 checksum How to use checksums |
05bc82565cba048a70a7af843d7aecf87ef50f639b527f69c03a0b6f65bb693c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-manylinux_2_28_x86_64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 8.8 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
a57c48fe3daac9bb45617e6606da3df522e9b4daf1426a131b5657a84805f3d8
|
|
BLAKE2b-256 checksum How to use checksums |
bf6f29838ef7ce460489aae49ccac2090e449acbacfe0aec5febbc7e14dd43cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-manylinux_2_28_aarch64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 8.4 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
f36e529783ce5bddfc42b5e0f95416e8bdb7ff29727a2283667c760466782aff
|
|
BLAKE2b-256 checksum How to use checksums |
6b44468c7297e17fbb491aef6f3be0bd829ebe3a025d090469cfa7dc551187a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 8.1 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
d6749fcf23746d63cba59829e7e8e6d9361dd8bb8bea5b794e2ecdecb5e25c02
|
|
BLAKE2b-256 checksum How to use checksums |
78860787f46d57b45b23b51d2448668b13d61bdebb50910e497482a26d2b3131
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logRelease files / ggrust-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | ggrust-0.6.1-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 8.5 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
1d13ec0527df3e58f4684ad01264df0f7beddc28924a8d10eb2fe2142646928c
|
|
BLAKE2b-256 checksum How to use checksums |
3b6f0ceeb5fd72aa883a4f41a17ee50ae126be393e1e7461b39574af8943a286
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logSecurity for ggrust 0.6.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 7 files in this release have been uploaded with provenance metadata.
Attestation for ggrust-0.6.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.