charcoal
A declarative, DataFrame-native chart library for Polars. No browser. No Python. No C FFI.
[]
= "0.1.1"
Quickstart
use ;
use *;
Chart Types
| Chart | Method | Required Columns |
|---|---|---|
| Scatter | Chart::scatter(&df) |
.x(), .y() |
| Line | Chart::line(&df) |
.x(), .y() |
| Bar | Chart::bar(&df) |
.x(), .y() |
| Histogram | Chart::histogram(&df) |
.x() |
| Heatmap | Chart::heatmap(&df) |
.x(), .y(), .z() |
| Box Plot | Chart::box_plot(&df) |
.x(), .y() |
| Area | Chart::area(&df) |
.x(), .y() |
Output Formats
| Format | Method | Feature Flag |
|---|---|---|
| SVG string | chart.svg() |
none |
| SVG file | chart.save_svg("out.svg") |
none |
| Standalone HTML | chart.save_html("out.html") |
none |
| PNG / JPEG / WEBP | chart.save_png("out.png") |
static |
| evcxr notebook | chart.display() |
notebook |
Feature Flags
| Feature | Enables | Extra Dependencies |
|---|---|---|
| (default) | SVG and HTML output | — |
static |
PNG/JPEG/WEBP raster export | resvg (pure Rust) |
notebook |
Inline display in evcxr | evcxr_runtime |
ndarray |
Array2<f64> input for heatmaps |
ndarray |
interactive |
Plotly.js interactive HTML export | none |
Themes
Default // clean light theme
Dark // dark background
Minimal // no gridlines, minimal chrome
Colorblind // Wong 8-color palette
Error Quality
charcoal errors tell you what went wrong, where, and what to do next:
CharcoalError::ColumnNotFound
column "sepal_lenght" not found
Did you mean: sepal_length
Available: sepal_length, sepal_width, petal_length, petal_width, species
Null Handling
Every column role has a documented null policy. Nulls are never silently dropped without a warning. Access warnings after rendering:
let chart = scatter
.x
.y
.build?;
for warning in chart.warnings
Row Limits
- Above 500k rows: warning emitted, scatter points subsampled
- Above 1M rows:
.build()returnsErr(CharcoalError::DataTooLarge)
Configure the limit via the builder:
scatter
.x
.y
.row_limit
.build?;
Alternatives
Plotters is a low-level drawing library that gives you full control over rendering primitives, but axis scaling, layout, and data mapping are all your responsibility. charcoal trades that flexibility for a DataFrame-in, chart-out API: if your data is already in Polars, charcoal needs one builder chain where Plotters needs a full rendering pipeline.
plotly wraps Plotly.js and produces rich interactive charts, but output requires a browser and a JavaScript runtime at view time. charcoal targets static, self-contained SVG and HTML — no JavaScript engine, no network dependency, embeddable anywhere.
charts-rs produces SVG output with a similar philosophy but uses a JSON/config-driven API and has no Polars integration. charcoal is built around Polars DataFrames as the primary input, so column selection, null handling, and type inference come for free.
License
Licensed under either of MIT or Apache 2.0 at your option.