Charton - A versatile plotting library for Rust

May 4, 2026 · View on GitHub

English | 简体中文

Charton - A versatile plotting library for Rust

Altair-style declarative plotting for Rust. High-performance, Polars-native, and Wasm-ready.

"Really nice project. ... This works perfectly as an ecosystem."Ritchie Vink, Creator of Polars

Crates.io Documentation Build Status License

Charton is a high-performance Rust plotting library featuring a declarative API inspired by Altair. It provides native Polars support and bridges the gap to the Python visualization ecosystem (Altair/Matplotlib). Integrated with evcxr_jupyter, it enables seamless interactive data exploration in notebooks.

Altair

Altair

Matplotlib

Matplotlib

Stacked Bar Chart

Stacked Bar Chart

Grouped Bar Chart with Errorbar

Grouped Bar With Errorbar

Density

Density

Histogram

Histogram

2d Density

2d Density Chart

Heatmap

Heatmap

Grouped Boxplot

Grouped Boxplot

Cumulative Frequency

Cumulative Frequency

Distribution

Distribution

Pie

Pie

Donut

Donut

Rose

Rose

Nightingale

Nightingale

Simple Stacked Area

Simple Stack Area

Normalized Stacked Area

Normalized Stacked Area

Steamgraph

Steamgraph

Beeswarm

Beeswarm

Strip

Strip

Installation

Add to Cargo.toml:

[dependencies]
charton = "0.5"                                         # Standard (Single-threaded)
charton = { version = "0.5", features = ["parallel"] }  # Multi-threaded processing
charton = { version = "0.5", features = ["png"] }       # With PNG support
charton = { version = "0.5", features = ["pdf"] }       # With PDF support
charton = { version = "0.5", features = ["bridge"] }    # With Altair/Matplotlib interop

Quick Start

Charton provides a high-level, declarative API. Standard visualizations can be generated using a concise one-liner syntax:

use charton::prelude::*;

// Data: Physical measurements (Height vs. Weight)
let height = vec![160.0, 165.0, 170.0, 175.0, 180.0];
let weight = vec![55.0, 62.0, 68.0, 75.0, 82.0];

// One-liner plotting
chart!(height, weight)?.mark_point()?.encode((alt::x("height"), alt::y("weight")))?.save("out.svg")?;

From Macros to Production API

While the chart! macro is a convenient syntactic sugar for rapid prototyping and simple scripts, the underlying Chart::build API is recommended for production environments where explicit data handling is required.

1. Professional Build API

For complex applications, use Chart::build to gain full control over the Dataset lifecycle.

let ds = Dataset::new()
    .with_column("height", height)?
    .with_column("weight", weight)?;

Chart::build(ds)? // Equivalent to chart!(ds)?
    .mark_point()?
    .encode((alt::x("height"), alt::y("weight")))?
    .save("out.svg")?;

Tip: Use add_column instead if you need to add columns dynamically within loops or conditional logic.

2. Polars Integration

For Polars users, Charton provides the load_polars_df! macro to seamlessly convert a DataFrame into a Charton-ready Dataset.

use polars::prelude::*;

let df = df![
    "height" => vec![160.0, 165.0, 170.0, 175.0, 180.0],
    "weight" => vec![55.0, 62.0, 68.0, 75.0, 82.0]
]?;

// Efficiently convert Polars DataFrame to Charton Dataset
let ds = load_polars_df!(df)?;

Chart::build(ds)? // Equivalent to chart!(ds)?
    .mark_point()?
    .encode((alt::x("height"), alt::y("weight")))?
    .save("out.svg")?;

Compatibility Note: Charton uses versioned macros to handle Polars' rapid API evolutions. Versions below 0.42 are no longer supported.

Polars VersionMacro to UseStatus
0.53+load_polars_df!(df)?Latest (Standard)
0.42 - 0.52load_polars_v42_52!(df)?Legacy Support
< 0.42N/AUnsupported

Layered Grammar

Inspired by the Grammar of Graphics (as seen in ggplot2 and Altair), Charton replaces rigid templates with a modular, layer-based system. Visualizations are constructed by stacking atomic marks, offering infinite flexibility beyond fixed chart types.

// Create individual layers
let line = chart!(height, weight)?
    .mark_line()?
    .encode((alt::x("height"), alt::y("weight")))?;

let point = chart!(height, weight)?
    .mark_point()?
    .encode((alt::x("height"), alt::y("weight")))?;

// Combine into a composite chart
line.and(point).save("layered.svg")?;

Interactive Notebooks (Jupyter)

Charton integrates with evcxr_jupyter for interactive data exploration. Replacing .save() with .show() renders SVGs directly within notebook cells:

evcxr jupyter

WebAssembly and Frontend

Charton supports WebAssembly and modern web frontend; please refer to Charton Docs for details (Docs are in the outlining stage).

Leveraging External Plotting Power

Charton bridges Rust with mature visualization ecosystems like Altair and Matplotlib via a high-speed IPC, enabling users to leverage diverse, professional-grade plotting tools within a unified workflow. please refer to Charton Docs for details (Docs are in the outlining stage).

True Layer Synchronization

Stop fighting with fragile, hard-coded patches. Charton treats scaling as a Single Source of Truth, making it possible to combine heterogeneous data sources into one plot while maintaining total mathematical consistency across every mark and axis. Comparison This figure demonstrates semantic synchronization in Charton. Point samples and bar backgrounds from different data sources are anchored to a unified scale, ensuring absolute color and spatial consistency.

Publish Quality

Designed for precision, Charton provides pixel-perfect control over complex marks. Whether it is a multi-layered ErrorBar for biomedical research or a high-density scatter plot for finance, Charton delivers the aesthetic rigor required by top-tier journals.

NEJM

NEJM

Charton

Charton

A reproduction of Figure 1A from the 2021 NEJM landmark study on once-weekly semaglutide for weight management, implemented using Charton.

Documentation

Please go to the Charton Docs for full documentation (Docs are in the outlining stage).

License

Charton is licensed under the Apache License 2.0.