Skip to content

Changelog

All notable changes to Ferrum are documented here.

Unreleased

No unreleased changes.

0.8.0

Grammar-of-graphics core with Rust rendering engine.

Added

  • 12 built-in themes — Paper Ink (default), Slate Citrus, Arctic Signal, Observable, Minimal, Dark, Publication, Economist, FiveThirtyEight, Solarized Light, Solarized Dark, plus explicit paper_ink for derivation.
  • 3 original categorical palettespaper_ink, slate_citrus, arctic_signal (8 colors each).
  • 9 continuous color schemescool_blue, warm_ochre, night_blue, electric_lime, signal_blue, ember_orange, blue_to_red, cyan_to_amber, blue_to_violet.
  • fm.hconcat() / fm.vconcat() — top-level convenience functions for multi-chart concatenation.
  • Chart.axis() — method for suppressing or restoring axis decorations.
  • Facet-before-transform — faceting now partitions data before statistical transforms run, so each panel gets its own transform subset.
  • Grouped smoothmark_smooth supports group-by; no explicit per-group layering needed.
  • Continuous colorbar — rendered alongside heatmaps and continuous-color charts.
  • Full Theme key wiring — all ferrum-spec.md §3.13 keys plumbed end-to-end from Python through Rust renderer. Unknown keys raise ValueError at construction.
  • Model diagnostics (Phase 10)ModelSource, ComparedModelSource, 32 visualizer classes, 31 figure-level helpers covering classification, regression, feature explanation, model selection, and clustering.
  • 9 figure-level helpersdisplot, catplot, relplot, lmplot, residplot, pairplot, heatmap, clustermap, jointplot.
  • 54 mark methods — primitives, statistical, distribution, uncertainty, scale-aware, and diagnostic marks.
  • DataFrame pluralism — polars, pandas, modin, cuDF, dask, ibis, and pyarrow all accepted via Chart(data).
  • Title renderingChart.properties(title="...") rendered in the SVG with theme-controlled typography.
  • Grid lines — theme-controlled grid rendering with configurable color, width, dash, and opacity.
  • Legend — categorical and continuous legends with theme-controlled positioning and styling.
  • Interactive rendering (Phase 11)Chart.interactive() switches to a GPU-backed WASM renderer with selections, zoom/pan, linked views, and tooltips. Backed by anywidget for Jupyter integration.
  • Selection APIselection_point, selection_interval, selection_single, selection_multi for declaring interactive state. Conditional encodings via sel.when(...).otherwise(...).
  • SelectionMark — configurable brush styling for interval selections.
  • InteractiveChart — anywidget-based Jupyter widget with on_selection_change callback and self-contained HTML export via .save().
  • Scene graph renderer — Rust-side render_interactive produces a SceneGraph JSON consumed by the WASM GPU renderer.
  • compose_svg_horizontal / compose_svg_vertical / compose_svg_grid — low-level Rust SVG composition helpers.
  • t-SNE and UMAP in pure RustManifoldVisualizer runs both via manifolds-rs, no Python umap-learn dependency.
  • 7 new diagnostic helpersclassification_report_chart, class_balance_chart, cooks_distance_chart, prediction_error_chart, silhouette_chart, elbow_chart, manifold_chart.
  • mark_label — text labels with collision avoidance (avoid_overlap=True).
  • mark_image — image tiles from URL fields.
  • RenderConfig — per-chart auto-raster policy configuration (threshold, behavior, aggregate, colormap).
  • raster= keyword — one-off auto-raster override on .show(), .save(), .show_svg(), .show_png().
  • score() on visualizers — all Group A visualizers implement .score() for sklearn-protocol compatibility.
  • width= on mark_boxplot — API symmetry with other marks.
  • stroke, angle, fill_opacity channels — wired end-to-end to SVG attribute emission and WASM renderer.
  • Legend format= and columns= — kwargs now wired through to legend rendering.
  • Packed tooltips — field-level tooltip content sent via binary buffer for interactive performance.
  • Binary instance bridge — GPU data bypasses JSON serialization in interactive rendering.

Fixed

  • Facet encodingfacet=, facet_col=, facet_row= now correctly partition data into panels.
  • mark_tick y-rug — single-axis tick marks render correctly in both x and y orientations.
  • CoordFlip rendering — no longer drops violin paths or boxplot rects under coordinate flip.
  • Histogram multiple='stack'/'fill' — bin edges now align across groups.
  • calibration_chart rendering — layering wiring gap resolved; renders correctly via .show_svg().
  • Chart decompositionchart.py split into rendering, encoding helpers, and composition helpers for maintainability.

Changed

  • + operator always layers — no longer ambiguous between layering and concatenation. Use |, &, fm.hconcat(), or fm.vconcat() for concatenation.
  • Default theme identity is Paper Ink — warm cream background, blue marks, warm grid. Previously was Observable-style white background.
  • Default categorical palette is paper_ink — previously okabe_ito.