Saving & export¶
Ferrum charts render to SVG, PNG, HTML, and JSON — no system dependencies, no display server, no matplotlib. Every chart object (base charts, compound views, helper output, diagnostic charts) supports the same export surface.
Output methods¶
The export surface splits into three roles. The to_* converters return an in-memory value, .save() writes to disk, and .show() displays the chart.
| Method | Returns | Use case |
|---|---|---|
.to_svg() |
str |
Get SVG markup as a string |
.to_png() |
bytes |
Get PNG as raw bytes |
.to_html() |
str |
Get the interactive HTML page as a string |
.save(path) |
None |
Write SVG, PNG, HTML, JSON, or PDF to a file (format inferred from extension) |
.show() |
None |
Display inline in Jupyter or open in browser |
All of these methods are available on every chart object — base Chart, compound views (HConcatChart, VConcatChart, JointChart, RepeatChart), and diagnostic helper output.
Renamed from show_svg / show_png
.show_svg() and .show_png() still work as deprecated aliases of .to_svg() and .to_png(). They emit a DeprecationWarning and will be removed in a future release. The to_* names make the convention explicit: to_* returns a value, save writes to disk, show displays.
Output formats¶
| Format | Method | File extension | Notes |
|---|---|---|---|
| SVG | .to_svg() |
.svg |
Vector graphics. Default render path. |
| PNG | .to_png() |
.png |
Rasterized via resvg in Rust. No Cairo/Pillow needed. |
| HTML | .to_html() |
.html |
Self-contained interactive page with inlined WASM renderer. |
| JSON | .save("out.json") |
.json |
Chart spec as JSON — the same format as .to_json(). |
.save("out.pdf") |
.pdf |
Rasterized via resvg-py. No Ghostscript or Cairo needed. |
Saving to disk¶
.save() infers the format from the file extension:
import ferrum as fm
import polars as pl
df = pl.DataFrame({"x": [1.0, 2.0, 3.0], "y": [2.0, 4.0, 3.0]})
chart = fm.Chart(df).mark_point().encode(x="x", y="y")
chart.save("scatter.svg") # vector
chart.save("scatter.png") # raster
chart.save("scatter.html") # interactive (WASM inlined)
chart.save("scatter.json") # spec
Pass format= explicitly to override the extension:
Controlling auto-raster¶
At high mark counts (default threshold: 500,000), Ferrum transparently substitutes a raster image for per-element SVG marks. Override this per-call with raster=:
chart.to_svg(raster=False) # force vector even at high counts
chart.save("out.svg", raster=False)
chart.to_png(raster=True) # force raster even at low counts
For persistent control, attach a RenderConfig to the chart:
from ferrum import RenderConfig
config = RenderConfig(raster_threshold=1_000_000, raster_behavior="silent")
chart = chart.properties(render_config=config)
chart.save("out.svg") # auto-raster fires at 1M marks, silently
RenderConfig parameters: raster_threshold (mark count or None to disable), raster_behavior ("warn", "silent", "error"), raster_aggregate, and raster_scheme (the canonical colormap keyword; raster_cmap is a back-compat alias).
Getting raw bytes¶
For programmatic use (embedding in notebooks, serving from a web app, writing to S3):
svg_str = chart.to_svg() # str — complete <svg>…</svg> document
png_bytes = chart.to_png() # bytes — raw PNG data
html_str = chart.to_html() # str — self-contained interactive HTML page
.to_html() returns the same bytes that .save("out.html") would write, as a string. It accepts the same embed_wasm=, toolbar=, and raster= keywords as the HTML save path.
PDF export¶
chart.save("chart.pdf") exports a vector PDF using resvg-py under the hood — no Ghostscript, Cairo, or other system tool required. The same zero-dependency guarantee as PNG rasterization applies.
High-DPI PNG output¶
Pass scale= to to_png() or save() to produce higher-resolution PNG output. The default scale is 2.0 (2× pixel density, suitable for standard retina displays). Increase it for print-quality output:
The scale factor multiplies the chart's pixel dimensions: a 600 × 400 chart at scale=3.0 produces a 1800 × 1200 PNG.
PNG resolution
The scale= parameter is the recommended way to control PNG resolution. You can also increase width and height via .properties(width=1200, height=800), but scale= is simpler for DPI-scaling existing charts without changing their logical dimensions.
Displaying in Jupyter¶
In a Jupyter notebook, charts render automatically via _repr_svg_ — just put the chart as the last expression in a cell:
For interactive rendering (selections, zoom/pan), call .interactive() instead — see Interactive rendering.
Outside of a notebook, .show() writes a temporary SVG and opens it in the system browser.
HTML export¶
.save("file.html") produces a self-contained HTML file with the WASM GPU renderer and scene data inlined. No server, no CDN, no external dependencies — the file works offline in any modern browser.
When you need the page as a string instead of a file (templating, serving from a web app, embedding in another document), .to_html() returns the byte-identical HTML in memory.
This is the right format for sharing interactive charts via email, Slack, or static hosting.
Toolbar in exported HTML¶
By default, exported HTML files include the interactive toolbar (Pan, Box Zoom, Box Select, Reset, Save PNG). Pass toolbar=False to suppress it:
The default is toolbar=True. The toolbar= parameter has no effect on SVG, PNG, or JSON output — it is only meaningful for the HTML format.
toolbar= also works on composed views:
Compound views¶
All composition operators produce objects with the same export surface. A four-panel report saves exactly like a single chart:
report = (roc | calibration) & (confusion | residuals)
report.save("model_report.svg")
report.save("model_report.png")
No system dependencies¶
Ferrum's rendering pipeline is pure Rust. SVG rendering, PNG rasterization (resvg), and WASM compilation all happen inside the wheel. There is no dependency on Cairo, X11, Ghostscript, or any display server. pip install ferrum is the entire setup — charts render in Kubernetes, CI, SSH sessions, and headless containers.
Where to go next¶
- First plot for a quick start with rendering.
- Themes for controlling the visual style of exported charts.
- Interactive rendering for WASM-based interactive output.
- Composition for building multi-panel views before export.