Skip to content

ferrum

Top-level public surface of the ferrum package.

Ferrum — a statistical visualization library with a Rust core.

Theme

Immutable theme value class for chart styling.

Pass to Chart.theme(t) per-chart or activate process-wide via set_default_theme(t). Per-chart .theme() always wins at render time.

All keys listed in ferrum-spec.md §3.13 are plumbed end-to-end to the Rust renderer. Unknown keys raise ValueError at construction.

Parameters:

Name Type Description Default
background str

Chart background color as a CSS hex string (e.g. "#ffffff"). background_color accepted as an alias.

required
mark_color str

Default mark fill/stroke color for marks that have no explicit color encoding.

required
font_family optional

Default text styling for body text (axis titles, etc.).

required
font_weight optional

Default text styling for body text (axis titles, etc.).

required
font_color optional

Default text styling for body text (axis titles, etc.).

required
font_size optional

Default text styling for body text (axis titles, etc.).

required
title_font_family optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
title_font_size optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
title_font_weight optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
title_color optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
title_anchor optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
title_offset optional

Chart title styling. title_anchor ∈ {"start", "middle", "end"}. Unset values fall back to the corresponding body-text key (title_colorfont_color, etc.).

required
label_font_family optional

Tick label styling. Fall back to font_family / font_color.

required
label_color optional

Tick label styling. Fall back to font_family / font_color.

required
grid bool

Whether to draw grid lines (default True).

required
grid_color optional

Grid line styling. grid_dash is a list of dash lengths.

required
grid_width optional

Grid line styling. grid_dash is a list of dash lengths.

required
grid_dash optional

Grid line styling. grid_dash is a list of dash lengths.

required
grid_opacity optional

Grid line styling. grid_dash is a list of dash lengths.

required
axis_line bool

Whether to draw axis strokes (default True).

required
axis_line_color optional

Axis and tick styling.

required
axis_line_width optional

Axis and tick styling.

required
tick_color optional

Axis and tick styling.

required
tick_size optional

Axis and tick styling.

required
tick_width optional

Axis and tick styling.

required
point_size optional

Mark styling.

required
point_opacity optional

Mark styling.

required
line_stroke_width optional

Mark styling.

required
bar_corner_radius optional

Mark styling.

required
area_opacity optional

Mark styling.

required
opacity optional

Mark styling.

required
color_scheme str

Named categorical palette: one of paper_ink (default), slate_citrus, arctic_signal, okabe_ito, tableau10, set1, set2, paired, pastel, dark2. Sequential names (viridis, plasma, magma, inferno, cividis, cool_blue, warm_ochre, night_blue, electric_lime, signal_blue, ember_orange) and diverging names (rdbu, blue_to_red, cyan_to_amber, blue_to_violet) also accepted.

required
sequential_scheme str

Default sequential color ramp used by heatmaps, density plots, and other continuous-color charts when no explicit cmap is given. Must be one of the recognized sequential/diverging names. Defaults to "cool_blue" (Paper Ink).

required
diverging_scheme str

Default diverging color ramp used by correlation matrices and other diverging-color charts when no explicit cmap is given. Must be one of the recognized sequential/diverging names. Defaults to "blue_to_red" (Paper Ink).

required
legend_orient optional

Legend layout.

required
legend_direction optional

Legend layout.

required
legend_title_font_size optional

Legend layout.

required
padding optional

Spacing in pixels.

required
axis_title_padding optional

Spacing in pixels.

required
column_padding optional

Spacing in pixels.

required
row_padding optional

Spacing in pixels.

required
strip_background_color optional

Facet strip-title background color.

required

Raises:

Type Description
ValueError

If any keyword argument is not in the supported key list (see Theme._KNOWN_KEYS).

Examples:

>>> import ferrum as fm
>>> t = fm.Theme(background="#f9f9f9", grid=False, padding=16)
>>> t2 = t.update(mark_color="#e74c3c")
>>> t2
Theme(background='#f9f9f9', grid=False, mark_color='#e74c3c', padding=16)

update

update(**kwargs: Any) -> 'Theme'

Return a new Theme with the given properties overridden.

Passing None for a key removes that property from the derived theme. The source theme is unchanged (immutable).

Parameters:

Name Type Description Default
**kwargs any

Property overrides. Pass None to clear a property.

{}

Returns:

Type Description
Theme

A new Theme with the merged properties.

Examples:

>>> import ferrum as fm
>>> base = fm.Theme(grid=False, padding=12)
>>> with_bg = base.update(background_color="#222")

to_spec_dict

to_spec_dict() -> dict

Return a dict suitable for ferrum._core.render_svg(theme=...).

Resolves spec-defined fallbacks (e.g. title_color falls back to font_color if unset) and normalises the public Python alias background to the Rust binding's canonical background_color key. Rust sees a fully-resolved dict; no Option fallback chains in the binding.

Chart

Bases: _RenderMixin

Top-level chart value class.

Every method returns a new Chart — the object is effectively immutable and safe to reuse across branches of a pipeline. The fluent API follows the pattern::

fm.Chart(df).mark_point().encode(x="sepal_length", y="sepal_width")

Parameters:

Name Type Description Default
data DataFrame - like or None

Input data. Accepts Polars DataFrame, pandas DataFrame, PyArrow Table / RecordBatch, dict-of-arrays, list-of-records, or a 2-D NumPy array. Passed through ferrum._coerce.to_arrow_table at render time. None is allowed when composing layered charts that share a parent's data.

None
width int or 'container'

Chart width in pixels, or "container" to fill the parent element. Default is 600.

None
height int or 'container'

Chart height in pixels. Default is 400.

None
title str

Title rendered above the plot area.

None
description str

Accessible description attached to the SVG root (<title> element).

None

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> chart = fm.Chart(df).mark_point().encode(x="x", y="y")
>>> svg = chart.show_svg()

layer_names property

layer_names: list[str]

Named sub-layers after composite-mark desugar resolution.

Returns [] for single-mark charts with no layers. Accessing this property forces resolution of any pending _PendingMark.

show_svg

show_svg(*, raster: bool | None = None) -> str

Render the chart to an SVG string.

Parameters:

Name Type Description Default
raster bool or None

Override the auto-raster policy for this render only. False forces per-element SVG regardless of mark count. True forces raster aggregation. None uses the chart's RenderConfig policy.

None

Returns:

Type Description
str

SVG markup for the chart.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> svg = fm.Chart(df).mark_point().encode(x="x", y="y").show_svg()
>>> svg.startswith("<svg")
True

show_png

show_png(*, raster: bool | None = None) -> bytes

Render the chart to PNG bytes.

Parameters:

Name Type Description Default
raster bool or None

Override the auto-raster policy for this render only. False forces per-element rendering. True forces raster. None uses the chart's RenderConfig policy.

None

Returns:

Type Description
bytes

PNG-encoded image data.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> png = fm.Chart(df).mark_point().encode(x="x", y="y").show_png()
>>> png[:4] == b'\x89PNG'
True

save

save(path, *, format=None, embed_wasm=True, raster: bool | None = None) -> None

Save the chart to a file on disk.

Parameters:

Name Type Description Default
path str or Path

Destination file path. Extension determines the default format: .svg -> SVG, .png -> PNG, .html -> HTML, .json -> JSON.

required
format ('svg', 'png', 'html', 'json')

Explicit format override. None (default) infers from path.

"svg"
embed_wasm bool

For "html" format only. When True (default), the WASM binary is base64-inlined for single-file distribution.

True
raster bool or None

Override the auto-raster policy for this save only. False forces per-element output. True forces raster. None uses the chart's RenderConfig policy.

None

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> fm.Chart(df).mark_point().encode(x="x", y="y").save("/tmp/chart.svg")

show

show(*, raster: bool | None = None) -> None

Display the chart inline or in a browser.

Parameters:

Name Type Description Default
raster bool or None

Override the auto-raster policy for this render only. False forces per-element SVG regardless of mark count. True forces raster aggregation. None uses the chart's RenderConfig policy.

None

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4]})
>>> fm.Chart(df).mark_point().encode(x="x", y="y").show()

mark_point

mark_point(**kwargs) -> 'Chart'

Render data as points (scatter plot).

Parameters:

Name Type Description Default
size float

Point area in square pixels. Default is 36.

required
fill str

Fill colour override (CSS colour string or hex). Normally driven by the color encoding.

required
stroke str

Stroke colour for the point outline.

required
opacity float

Overall opacity in [0, 1].

required
filled bool

Whether points are filled. Default is True.

required
shape str

Point shape: "circle", "square", "cross", "diamond", "triangle-up", "triangle-down".

required
stroke_width float

Stroke width in pixels.

required
position Position

Position adjustment — fm.Jitter(), fm.Dodge(), etc.

required

Returns:

Type Description
Chart

New Chart with mark set to "point".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> fm.Chart(df).mark_point(size=60, opacity=0.7).encode(x="x", y="y")
Chart(mark='point', encoding=['x', 'y'])

mark_line

mark_line(**kwargs) -> 'Chart'

Render data as a connected line.

Parameters:

Name Type Description Default
stroke str

Stroke colour override.

required
stroke_width float

Line width in pixels. Default is 2.

required
opacity float

Overall opacity in [0, 1].

required
interpolate str

Line interpolation: "linear", "monotone", "step", "step-before", "step-after", "basis", "cardinal".

required
stroke_cap str

Line cap: "butt", "round", "square".

required
stroke_join str

Line join: "miter", "round", "bevel".

required
position Position

Position adjustment.

required

Returns:

Type Description
Chart

New Chart with mark set to "line".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> fm.Chart(df).mark_line(stroke_width=3, interpolate="monotone").encode(x="x", y="y")
Chart(mark='line', encoding=['x', 'y'])

mark_bar

mark_bar(**kwargs) -> 'Chart'

Render data as bars.

Parameters:

Name Type Description Default
fill str

Bar fill colour override.

required
stroke str

Bar stroke colour.

required
stroke_width float

Bar stroke width in pixels.

required
opacity float

Overall opacity in [0, 1].

required
corner_radius float

Rounded corner radius in pixels.

required
orient str

"vertical" (default) or "horizontal".

required
position Position

Position adjustment — fm.Stack(), fm.Dodge(), etc.

required

Returns:

Type Description
Chart

New Chart with mark set to "bar".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"cat": ["a", "b", "c"], "val": [10, 20, 15]})
>>> fm.Chart(df).mark_bar(corner_radius=4).encode(x="cat", y="val")
Chart(mark='bar', encoding=['x', 'y'])

mark_area

mark_area(**kwargs) -> 'Chart'

Render data as a filled area between the line and a baseline.

Parameters:

Name Type Description Default
fill str

Fill colour override.

required
stroke str

Border stroke colour.

required
stroke_width float

Border stroke width in pixels.

required
opacity float

Overall opacity in [0, 1].

required
interpolate str

Area boundary interpolation: "linear", "monotone", "step", "basis", "cardinal".

required
line bool

Whether to draw the top boundary as a line. Default is False.

required
position Position

Position adjustment — e.g. fm.Stack().

required

Returns:

Type Description
Chart

New Chart with mark set to "area".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> fm.Chart(df).mark_area(opacity=0.5, line=True).encode(x="x", y="y")
Chart(mark='area', encoding=['x', 'y'])

mark_rule

mark_rule(**kwargs) -> 'Chart'

Render a horizontal or vertical reference rule spanning the plot area.

A rule spans the full width (when y is encoded) or full height (when x is encoded). Encoding both x/x2 or y/y2 draws finite line segments instead.

Parameters:

Name Type Description Default
stroke str

Rule colour override.

required
stroke_width float

Rule width in pixels. Default is 1.

required
stroke_dash str or list

Dash pattern, e.g. "4,2".

required
opacity float

Overall opacity in [0, 1].

required
position Position

Position adjustment.

required

Returns:

Type Description
Chart

New Chart with mark set to "rule".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"y": [0.0]})
>>> fm.Chart(df).mark_rule(stroke="red", stroke_width=2).encode(y="y")
Chart(mark='rule', encoding=['y'])

mark_text

mark_text(**kwargs) -> 'Chart'

Render data values as text labels.

Requires a text encoding channel pointing at the column to display.

Parameters:

Name Type Description Default
fill str

Text colour override.

required
font_size float

Font size in points. Default is 11.

required
font_weight str or int

CSS font-weight, e.g. "bold", 400, 700.

required
align str

Horizontal alignment: "left", "center", "right".

required
baseline str

Vertical alignment: "top", "middle", "bottom", "alphabetic".

required
dx float

Horizontal pixel offset from the anchor point.

required
dy float

Vertical pixel offset from the anchor point.

required
angle float

Rotation in degrees.

required
limit float

Maximum rendered width in pixels; clips overflow.

required
position Position

Position adjustment.

required

Returns:

Type Description
Chart

New Chart with mark set to "text".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4], "label": ["A", "B"]})
>>> fm.Chart(df).mark_text(dy=-8).encode(x="x", y="y", text="label")
Chart(mark='text', encoding=['x', 'y', 'text'])

mark_tick

mark_tick(**kwargs) -> 'Chart'

Render data as short tick marks (rug / strip plot).

Parameters:

Name Type Description Default
stroke str

Tick colour override.

required
stroke_width float

Tick stroke width in pixels.

required
opacity float

Overall opacity in [0, 1].

required
band_size float

Tick length in pixels.

required
orient str

"vertical" (default ticks perpendicular to x) or "horizontal".

required
position Position

Position adjustment.

required

Returns:

Type Description
Chart

New Chart with mark set to "tick".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1.1, 2.3, 3.5, 2.2, 1.8]})
>>> fm.Chart(df).mark_tick().encode(x="x")
Chart(mark='tick', encoding=['x'])

mark_rect

mark_rect(**kwargs) -> 'Chart'

Render data as rectangles (heatmap cells, Gantt bars).

Requires x/x2 or y/y2 encoding pairs (or ordinal x/y for a heatmap cell grid).

Parameters:

Name Type Description Default
fill str

Rectangle fill colour override.

required
stroke str

Rectangle border stroke colour.

required
stroke_width float

Border stroke width in pixels.

required
opacity float

Overall opacity in [0, 1].

required
corner_radius float

Rounded corner radius in pixels.

required
position Position

Position adjustment.

required

Returns:

Type Description
Chart

New Chart with mark set to "rect".

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"row": ["A", "B"], "col": ["X", "Y"], "val": [1.0, 0.5]})
>>> fm.Chart(df).mark_rect().encode(x="col", y="row", color="val")
Chart(mark='rect', encoding=['x', 'y', 'color'])

mark_segment

mark_segment(*, position=None, **kwargs) -> 'Chart'

Render data as line segments from (x, y) to (x2, y2).

Distinct from mark_rule (axis-aligned only); segments may take any direction. Requires x, y, x2, y2 on the encoding.

Parameters:

Name Type Description Default
stroke str

Segment stroke colour override.

required
stroke_width float

Segment stroke width in pixels.

required
stroke_dash list of float

Dash pattern (alternating on/off pixel lengths).

required
opacity float

Stroke opacity in [0, 1].

required
position Position

Position adjustment.

None
**kwargs

Additional mark-style overrides forwarded to the segment layer.

{}

Returns:

Type Description
Chart

New Chart configured for segment rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [0, 1], "y": [0, 1], "x2": [1, 2], "y2": [1, 0]})
>>> fm.Chart(df).mark_segment().encode(x="x", y="y", x2="x2", y2="y2")
Chart(mark='segment', encoding=['x', 'y', 'x2', 'y2'])

mark_density

mark_density(*, position=None, **kwargs) -> 'Chart'

Render a kernel-density estimate (KDE) curve or filled contour.

When only x is encoded, draws a 1-D KDE area curve. When both x and y are encoded, renders a bivariate filled-contour density (routes through desugar_contour(fill=True)). Can be called before or after .encode().

Parameters:

Name Type Description Default
bandwidth float or 'scott' or 'silverman'

KDE bandwidth. "scott" and "silverman" use the corresponding rule-of-thumb estimates. Default is "scott".

required
kernel str

Kernel type: "gaussian", "tophat", "epanechnikov", "exponential", "linear", "cosine". Default is "gaussian".

required
extent list of float or None

[min, max] evaluation range. Defaults to data extent.

required
cumulative bool

Produce a CDF instead of a PDF. Default is False.

required
n int

Number of evaluation points. Default is 200.

required
multiple str

How to handle multiple densities when a color encoding is present: "layer" (default), "stack", "fill".

required
position Position

Position adjustment.

None

Returns:

Type Description
Chart

New Chart configured for density rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"val": [1.0, 2.1, 1.8, 3.0, 2.5]})
>>> fm.Chart(df).mark_density().encode(x="val")
Chart(mark='area', encoding=['x'])

mark_histogram

mark_histogram(*, position=None, **kwargs) -> 'Chart'

Render data as a histogram.

Bins the x-encoded column and encodes bin extents as x/x2 with counts (or densities) on y. Can be called before or after .encode(x=...).

Parameters:

Name Type Description Default
bin_count int

Target number of bins. Ignored when bin_width is set. Default is chosen automatically from Sturges' rule.

required
bin_width float

Exact bin width in data units. Overrides bin_count.

required
density bool

Normalise counts to a probability density. Default is False.

required
right bool

Whether bins are closed on the right. Default is True.

required
cumulative bool

Render a cumulative histogram. Default is False.

required
multiple str

How to handle grouped histograms when a color encoding is present: "layer" (default), "stack", "dodge".

required
position Position

Position adjustment.

None

Returns:

Type Description
Chart

New Chart configured for histogram rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"val": [1.0, 1.2, 2.3, 3.1, 2.8, 1.5]})
>>> fm.Chart(df).mark_histogram(bin_count=5).encode(x="val")
Chart(mark='bar', encoding=['x', 'x2', 'y'])

mark_smooth

mark_smooth(*, position=None, **kwargs) -> 'Chart'

Render a smoothed regression line with optional confidence interval band.

Fits a smooth curve through (x, y) data using the method specified by method. When ci is set, emits a layered ribbon (CI band) + line chart. Can be called before or after .encode(x=..., y=...).

Parameters:

Name Type Description Default
method str

Smoothing method: "loess" (default), "linear", "quadratic", "cubic", "log", "sqrt".

required
degree int

Polynomial degree for "linear"/"quadratic"/"cubic".

required
bandwidth float

LOESS bandwidth fraction in (0, 1]. Default is 0.75.

required
n int

Number of evaluation points along the x range. Default is 200.

required
ci float or None

Confidence level for the interval band, e.g. 0.95. When set, produces a layered ribbon + line chart. Default is None.

required
groupby str

Group-key column (Utf8). When set, the smooth is computed independently per group and the group column is preserved in the output so downstream color= encoding maps to it.

required
position Position

Position adjustment.

None

Returns:

Type Description
Chart

New Chart configured for smooth rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1.0, 2.0, 3.0, 4.0], "y": [1.1, 1.9, 3.1, 4.0]})
>>> fm.Chart(df).mark_smooth(method="linear", ci=0.95).encode(x="x", y="y")
Chart(mark='line', encoding=['x', 'y'])

mark_boxplot

mark_boxplot(*, extent=1.5, size=None, width=None, outliers=True, color_field=None, horizontal=False, position=None, **mark_kwargs) -> 'Chart'

Render a Tukey boxplot via composite mark desugaring.

Desugars to a multi-layer chart: box (IQR rect), upper and lower whisker rules, median rule, and (optionally) outlier points. Requires a categorical x encoding and a continuous y (or the reverse when horizontal=True).

Parameters:

Name Type Description Default
extent float

Whisker reach as a multiple of IQR. Default is 1.5.

1.5
size float or None

Box band-width as a fraction of the category band (default 0.6). Alias: width.

None
width float or None

Alias for size. Controls box band-width as a fraction of the category band. When both size and width are provided, size takes precedence.

None
outliers bool

Whether to draw outlier points beyond the whiskers. Default is True.

True
color_field str or None

Column name to drive per-group fill colour on the box layer.

None
horizontal bool

Swap x and y axes so boxes run horizontally. Default is False.

False
position Position

Position adjustment — e.g. fm.Dodge() for side-by-side boxes.

None
**mark_kwargs

Additional mark-style overrides forwarded to each constituent layer.

{}

Returns:

Type Description
Chart

New layered Chart representing the boxplot.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"species": ["a"]*5 + ["b"]*5, "val": [1,2,3,2,1,4,5,4,5,6]})
>>> fm.Chart(df).mark_boxplot().encode(x="species", y="val")
Chart(mark='point', encoding=[])

mark_boxen

mark_boxen(*, k_depth: str = 'tukey', k_proportion: float = 0.007, outlier_threshold: float = 1.5, palette=None, horizontal: bool = False, color_field=None, position=None, **mark_kwargs) -> 'Chart'

Render a letter-value (boxen) plot via composite mark desugaring.

Produces nested rectangular bands for each letter-value depth, a median rule, and an outlier-point layer via the LetterValue transform. Requires a categorical x encoding and a continuous y (or the reverse when horizontal=True).

Parameters:

Name Type Description Default
k_depth ('proportion', 'trustworthy', 'full')

Rule for choosing the number of letter-value levels.

"proportion"
k_proportion float

Proportion parameter used when k_depth="proportion". Default is 0.007.

0.007
outlier_threshold float

IQR multiple beyond which points are considered outliers. Default is 1.5.

1.5
palette list of str or None

Colour palette applied to successive depth bands. None uses the active theme's categorical palette.

None
horizontal bool

Swap axes so bands run horizontally. Default is False.

False
color_field str or None

Column name to drive per-group colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Additional mark-style overrides forwarded to constituent layers.

{}

Returns:

Type Description
Chart

New layered Chart representing the boxen plot.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"group": ["a"]*20 + ["b"]*20,
...                    "val": list(range(20)) + list(range(10, 30))})
>>> fm.Chart(df).mark_boxen().encode(x="group", y="val")
Chart(mark='point', encoding=[])

mark_errorbar

mark_errorbar(*, extent='ci', ticks=True, position=None, **mark_kwargs) -> 'Chart'

Render error bars via the ErrorExtent transform.

Computes extent values (CI, SD, SEM, or IQR) per group defined by the x encoding, then draws a vertical rule spanning the extent with optional tick caps.

Parameters:

Name Type Description Default
extent ('ci', 'stderr', 'stdev', 'iqr')

Extent measure: confidence interval ("ci"), standard error ("stderr"), standard deviation ("stdev"), or interquartile range ("iqr").

"ci"
ticks bool

Whether to draw horizontal tick caps at the extent endpoints. Default is True.

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to constituent rule/tick layers.

{}

Returns:

Type Description
Chart

New layered Chart representing the error bars.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"group": ["a"]*10 + ["b"]*10,
...                    "val": list(range(10)) + list(range(5, 15))})
>>> fm.Chart(df).mark_errorbar(extent="stdev").encode(x="group", y="val")
Chart(mark='point', encoding=[])

mark_errorband

mark_errorband(*, extent='ci', borders=False, position=None, **mark_kwargs) -> 'Chart'

Render an error band (ribbon) via the ErrorExtent transform.

Similar to mark_errorbar but renders the extent as a filled ribbon rather than whisker rules. Optionally draws border lines at the upper and lower extent edges.

Parameters:

Name Type Description Default
extent ('ci', 'stderr', 'stdev', 'iqr')

Extent measure: confidence interval ("ci"), standard error ("stderr"), standard deviation ("stdev"), or interquartile range ("iqr").

"ci"
borders bool

Whether to draw line borders at the band edges. Default is False.

False
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides (e.g. opacity) forwarded to the ribbon layer.

{}

Returns:

Type Description
Chart

New layered Chart representing the error band.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": list(range(10)), "y": [float(i) for i in range(10)]})
>>> fm.Chart(df).mark_errorband(extent="ci", borders=True).encode(x="x", y="y")
Chart(mark='point', encoding=[])

mark_ribbon

mark_ribbon(*, opacity=0.3, interpolate='linear', position=None, **mark_kwargs) -> 'Chart'

Render a ribbon (filled area between y and y2 along x).

Requires both y and y2 encoding channels. Typically used to visualise confidence intervals alongside a mark_line in the same layered chart.

Parameters:

Name Type Description Default
opacity float

Fill opacity of the ribbon. Default is 0.3.

0.3
interpolate str

Boundary interpolation: "linear", "monotone", "step", "basis", "cardinal". Default is "linear".

'linear'
position Position

Position adjustment.

None
**mark_kwargs

Additional mark-style overrides (e.g. fill, stroke).

{}

Returns:

Type Description
Chart

New Chart configured for ribbon rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y_lo": [0.5, 1.5, 2.5], "y_hi": [1.5, 2.5, 3.5]})
>>> fm.Chart(df).mark_ribbon().encode(x="x", y="y_lo", y2="y_hi")
Chart(mark='ribbon', encoding=['x', 'y', 'y2'])

mark_contour

mark_contour(*, bandwidth='scott', thresholds=6, smooth=True, fill=False, cmap=None, position=None, **mark_kwargs) -> 'Chart'

Render a bivariate contour plot via Kde2D + Contour transforms.

Estimates a 2-D kernel density and draws iso-contour lines (or filled contour regions when fill=True). Requires both x and y encodings.

Parameters:

Name Type Description Default
bandwidth float or 'scott' or 'silverman'

Bandwidth for the 2-D KDE. Default is "scott".

'scott'
thresholds int or list of float

Number of evenly-spaced contour levels, or an explicit list of density thresholds. Default is 6.

6
smooth bool

Whether to smooth contour paths via Gaussian filtering before contouring. Default is True.

True
fill bool

Render filled contour regions instead of contour lines. Default is False.

False
cmap str or None

Colour map name applied to contour levels. None (default) defers to the theme's sequential scheme.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the polygon/path layers.

{}

Returns:

Type Description
Chart

New layered Chart configured for contour rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1.0, 2.0, 3.0, 2.0, 1.5], "y": [4.0, 5.0, 4.5, 3.0, 4.0]})
>>> fm.Chart(df).mark_contour(thresholds=4, fill=True).encode(x="x", y="y")
Chart(mark='polygon', encoding=['x', 'y'])

mark_violin

mark_violin(*, bandwidth='scott', inner='box', position=None, **mark_kwargs) -> 'Chart'

Render violin plots via the Violin transform.

Estimates a mirrored KDE per group and overlays an optional inner summary (box, quartile lines, or individual points). Requires a categorical x and continuous y encoding (or swapped when horizontal is set).

Parameters:

Name Type Description Default
bandwidth float or 'scott' or 'silverman'

KDE bandwidth. Default is "scott".

'scott'
inner ('box', 'quartile', 'point', 'none')

Inner mark drawn on top of each violin: "box" — IQR box + median rule, "quartile" — three horizontal quartile rules, "point" — individual data points (strip), "none" — no inner mark.

"box"
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the violin polygon layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for violin rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"group": ["a"]*10 + ["b"]*10,
...                    "val": list(range(10)) + list(range(5, 15))})
>>> fm.Chart(df).mark_violin(inner="quartile").encode(x="group", y="val")
Chart(mark='polygon', encoding=['x', 'y'])

mark_qq

mark_qq(*, distribution='normal', dequantize=False, line=True, position=None, **mark_kwargs) -> 'Chart'

Render a quantile-quantile plot.

Computes theoretical vs. sample quantiles via the QQ transform. Reads the sample column from the x encoding; y is ignored.

Parameters:

Name Type Description Default
distribution ('normal', 'uniform', 'exponential', 'lognormal')

Theoretical distribution to compare the sample against.

"normal"
dequantize bool

Whether to apply rank-based dequantization before comparison. Default is False.

False
line bool

Whether to overlay a 45-degree reference line. Default is True.

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the scatter layer.

{}

Returns:

Type Description
Chart

New Chart configured for QQ rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"val": [1.2, 0.8, 1.5, -0.5, 0.3, 2.1, -1.0, 0.6]})
>>> fm.Chart(df).mark_qq(distribution="normal").encode(x="val")
Chart(mark='point', encoding=['x'])

mark_raster

mark_raster(*, aggregate='count', field=None, cmap=None, resolution='screen', blend='alpha', min_count=None, log_scale=False, position=None, **mark_kwargs) -> 'Chart'

Render a 2-D raster (pixel heatmap) via the Raster transform.

Bins data into a pixel grid and colours each pixel by an aggregate statistic. Most useful for very large datasets where a scatter plot would overplot. Requires x and y encodings.

Parameters:

Name Type Description Default
aggregate str

Aggregate function applied to each pixel bin: "count" (default), "sum", "mean", "min", "max". When aggregate is not "count", field must be provided.

'count'
field str or None

Column name to aggregate. Required unless aggregate="count".

None
cmap str or None

Colour map name. None (default) defers to the theme's sequential scheme.

None
resolution 'screen' or int

Pixel grid resolution. "screen" (default) matches the rendered chart dimensions; pass an integer to set an explicit grid width.

'screen'
blend str

Alpha-compositing blend mode. Default is "alpha".

'alpha'
min_count int or None

Minimum count threshold; pixels below this are rendered transparent. None (default) shows all pixels.

None
log_scale bool

Apply a log transform to pixel values before colour mapping. Default is False.

False
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the image layer.

{}

Returns:

Type Description
Chart

New Chart configured for raster rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1.0, 2.0, 3.0, 2.5], "y": [4.0, 5.0, 4.5, 4.0]})
>>> fm.Chart(df).mark_raster(cmap="plasma").encode(x="x", y="y")
Chart(mark='image', encoding=['x', 'y'])

mark_hex

mark_hex(*, bin_size=None, aggregate='count', field=None, cmap=None, stroke=None, stroke_width=0, position=None, **mark_kwargs) -> 'Chart'

Render a hexagonal bin plot via the Hex transform.

Bins data into a regular hexagonal grid and colours each cell by an aggregate statistic. Requires x and y encodings.

Parameters:

Name Type Description Default
bin_size float or None

Hexagon radius in data units. None (default) chooses a size automatically from the data range and chart dimensions.

None
aggregate str

Aggregate function: "count" (default), "sum", "mean", "min", "max".

'count'
field str or None

Column to aggregate. Required unless aggregate="count".

None
cmap str or None

Colour map name. None (default) defers to the theme's sequential scheme.

None
stroke str or None

Hex border colour. None (default) means no border.

None
stroke_width float

Hex border width in pixels. Default is 0.

0
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the polygon layer.

{}

Returns:

Type Description
Chart

New Chart configured for hexagonal binning.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1.0, 2.0, 1.5, 3.0, 2.5], "y": [4.0, 5.0, 4.5, 3.0, 4.0]})
>>> fm.Chart(df).mark_hex(bin_size=0.5).encode(x="x", y="y")
Chart(mark='polygon', encoding=['x', 'y'])

mark_swarm

mark_swarm(*, size=4, orient='vertical', spacing=1.0, side='both', dodge=None, position=None, **mark_kwargs) -> 'Chart'

Render a beeswarm (strip swarm) plot via the Swarm transform.

Computes non-overlapping point positions along the categorical axis using a deterministic placement algorithm seeded for reproducibility. Requires a continuous y (or x) and an optional categorical grouping axis.

Parameters:

Name Type Description Default
size float

Point diameter in pixels. Default is 4.

4
orient ('vertical', 'horizontal')

Orientation of the swarm axis. "vertical" spreads points along x; "horizontal" spreads along y.

"vertical"
spacing float

Minimum spacing between point centres as a fraction of size. Default is 1.0.

1.0
side ('both', 'left', 'right')

Side of the axis on which points can be placed.

"both"
dodge str or None

Column name to use as a secondary grouping variable for dodging. None (default) means no dodging.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the point layer.

{}

Returns:

Type Description
Chart

New Chart configured for beeswarm rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"group": ["a"]*8 + ["b"]*8, "val": list(range(16))})
>>> fm.Chart(df).mark_swarm(size=6).encode(x="group", y="val")
Chart(mark='point', encoding=['x', 'y'])

mark_function

mark_function(fn, *, domain=None, n=200, clip=True, position=None, **mark_kwargs) -> 'Chart'

Render a mathematical function as a line.

Evaluates fn(xs) on n evenly-spaced x values in the specified domain and renders the result as a line. The input data on the chart is replaced with the synthetic dataset; use + composition to overlay a function on a scatter chart.

Parameters:

Name Type Description Default
fn callable

A function accepting a 1-D NumPy array of x values and returning a 1-D array of y values.

required
domain list of float or None

[x_min, x_max] evaluation range. None (default) infers the range from the parent chart's x column if available, otherwise raises ValueError.

None
n int

Number of evaluation points. Default is 200.

200
clip bool

Whether to clip rendered line to the plot viewport. Default is True.

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to the line layer (e.g. stroke, stroke_width).

{}

Returns:

Type Description
Chart

New Chart whose data is the synthetic (x, y) table.

Raises:

Type Description
ValueError

When domain is not provided and no parent x data can be inferred.

Examples:

>>> import ferrum as fm
>>> import numpy as np
>>> import polars as pl
>>> fm.Chart(None).mark_function(np.sin, domain=[0, 6.28], n=100)
Chart(mark='line', encoding=['x', 'y'])

mark_residuals

mark_residuals(*, kind: str = 'studentized', reference_line: bool = True, cook_threshold: float | str | None = None, color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a residuals diagnostic plot.

Plots fitted values (y_pred) on x against residuals (raw or studentized) on y. Data must carry the schema emitted by ModelSource.predictions(): y_true, y_pred, residual, studentized_residual, and cooks_distance.

When reference_line=True a sentinel _ref_zero column is injected so the downstream mark_rule draws a single horizontal line at y=0.

When cook_threshold is set, high-leverage points (Cook's D above the threshold) are highlighted as a second mark_point layer drawn in red with a black outline.

Parameters:

Name Type Description Default
kind ('studentized', 'raw')

Residual type to plot on the y axis. "studentized" uses studentized_residual; "raw" uses residual.

"studentized"
reference_line bool

Whether to draw a horizontal reference line at y=0. Default is True.

True
cook_threshold float, "auto", or None

Cook's Distance threshold for outlier highlighting. "auto" uses the conventional 4 / n rule. None (default) disables outlier highlighting.

None
color_field str or None

Column name to drive per-group colour on the scatter layer.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the scatter layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for residuals rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.predictions()).mark_residuals(cook_threshold="auto")
Chart(mark='point', encoding=[])

mark_prediction_error

mark_prediction_error(*, reference_line: bool = True, ci: float | None = None, reference_band: bool = False, color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render an actual-vs-predicted plot.

Plots y_true on x against y_pred on y as scatter points. When reference_line=True the data is pre-sorted ascending by y_true so the downstream mark_line renders a monotonic y=x diagonal. Data must carry y_true and y_pred columns (schema from ModelSource.predictions()).

Parameters:

Name Type Description Default
reference_line bool

Whether to overlay a y=x identity reference line. Default is True.

True
ci float or None

Confidence level for a prediction-interval band (e.g. 0.95). None (default) omits the band.

None
reference_band bool

Whether to draw a shaded reference band around the identity line. Default is False.

False
color_field str or None

Column name to drive per-group colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the scatter layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for prediction-error rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.predictions()).mark_prediction_error(ci=0.95)
Chart(mark='point', encoding=[])

mark_roc

mark_roc(*, average: str | None = None, reference_line: bool = True, annotate_auc: bool = False, color_field: str | None = 'class', position=None, **mark_kwargs) -> 'Chart'

Render a Receiver Operating Characteristic (ROC) curve.

Plots false-positive rate (fpr) on x against true-positive rate (tpr) on y as a line per class. Data must carry the schema emitted by ModelSource.roc_curve(): fpr, tpr, threshold, class, auc. When reference_line=True the data is pre-sorted ascending by fpr before rendering.

Parameters:

Name Type Description Default
average str or None

When the data contains a macro/micro average row with class=average, pass "macro" or "micro" to keep only that average line. None (default) renders all classes.

None
reference_line bool

Whether to overlay a diagonal chance-level reference line (TPR=FPR). Default is True.

True
annotate_auc bool

Whether to annotate each curve with its AUC value. Default is False.

False
color_field str or None

Column name to drive per-class colour. Default is "class".

'class'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for ROC rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.roc_curve()).mark_roc(annotate_auc=True)
Chart(mark='point', encoding=[])

mark_pr

mark_pr(*, average: str | None = None, annotate_ap: bool = False, iso_lines: bool = False, color_field: str | None = 'class', position=None, **mark_kwargs) -> 'Chart'

Render a Precision-Recall (PR) curve.

Plots recall on x against precision on y as a line per class. Data must carry the schema emitted by ModelSource.pr_curve(): precision, recall, threshold, class, ap.

Parameters:

Name Type Description Default
average str or None

Filter to a specific average type row (e.g. "macro"). None (default) renders all classes.

None
annotate_ap bool

Whether to annotate each curve with its average-precision (AP) value. Default is False.

False
iso_lines bool

Whether to draw iso-F1 reference lines in the background. Default is False.

False
color_field str or None

Column name to drive per-class colour. Default is "class".

'class'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for PR-curve rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.pr_curve()).mark_pr(annotate_ap=True)
Chart(mark='point', encoding=[])

mark_calibration

mark_calibration(*, n_bins: int = 10, strategy: str = 'uniform', reference_line: bool = True, color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a calibration (reliability) curve.

Plots mean predicted probability on x against fraction of positive outcomes (empirical probability) on y. A perfectly calibrated model lies on the diagonal. Data must carry the schema emitted by ModelSource.calibration_curve(): mean_predicted, fraction_positive, count.

When reference_line=True the data is pre-sorted ascending by mean_predicted before rendering.

Parameters:

Name Type Description Default
n_bins int

Number of calibration bins. Default is 10.

10
strategy ('uniform', 'quantile')

Binning strategy. "uniform" uses equally-spaced bins; "quantile" uses equal-frequency bins.

"uniform"
reference_line bool

Whether to overlay a perfect-calibration diagonal reference line. Default is True.

True
color_field str or None

Column name to drive per-group colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for calibration rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.calibration_curve()).mark_calibration(n_bins=15)
Chart(mark='point', encoding=[])

mark_gain

mark_gain(*, reference_line: bool = True, color_field: str | None = 'class', position=None, **mark_kwargs) -> 'Chart'

Render a cumulative gain chart.

Plots percent of population contacted on x against the cumulative gain (fraction of positive cases captured) on y. Data must carry the schema emitted by ModelSource.cumulative_gain(): percent_population, gain, class. The no-skill diagonal baseline is encoded as rows with class='baseline'.

Parameters:

Name Type Description Default
reference_line bool

Whether to draw the no-skill baseline diagonal. Default is True.

True
color_field str or None

Column name to drive per-class colour. Default is "class".

'class'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for cumulative-gain rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.cumulative_gain()).mark_gain()
Chart(mark='point', encoding=[])

mark_lift

mark_lift(*, reference_line: bool = True, color_field: str | None = 'class', position=None, **mark_kwargs) -> 'Chart'

Render a lift curve chart.

Plots percent of population targeted on x against lift (ratio of positive-case density to baseline) on y. Data must carry the schema emitted by ModelSource.lift_curve(): percent_population, lift, class. The no-skill lift=1 baseline is encoded as rows with class='baseline'.

Parameters:

Name Type Description Default
reference_line bool

Whether to draw the lift=1 baseline rule. Default is True.

True
color_field str or None

Column name to drive per-class colour. Default is "class".

'class'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for lift-curve rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.lift_curve()).mark_lift()
Chart(mark='point', encoding=[])

mark_discrimination_threshold

mark_discrimination_threshold(*, metrics: tuple[str, ...] = ('precision', 'recall', 'f1', 'queue_rate'), n_thresholds: int = 50, threshold_line: bool = False, optimum_label: bool = True, position=None, **mark_kwargs) -> 'Chart'

Render a discrimination-threshold sweep plot.

Sweeps the decision threshold from 0 to 1 and plots multiple metrics (precision, recall, F1, queue rate) as lines against the threshold value. Data must be in long form with columns threshold, metric, value — the figure builder handles unpivoting from ModelSource.discrimination_threshold() output.

Parameters:

Name Type Description Default
metrics tuple of str

Metric names to include. Default is ("precision", "recall", "f1", "queue_rate").

('precision', 'recall', 'f1', 'queue_rate')
n_thresholds int

Number of evenly-spaced threshold steps to evaluate. Default is 50.

50
threshold_line bool

Whether to draw a vertical rule at the optimal threshold. Default is False.

False
optimum_label bool

Whether to overlay a text annotation at the F1-optimum point showing "max F1 = {f1:.3f} @ t={threshold:.2f}". Default True (Schwabish C7 audit-rework, 2026-05-12). The mark's data_transform injects _optimum_x / _optimum_y / _optimum_text sentinel columns from the long-form data; the desugar emits a mark_text layer.

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for discrimination-threshold rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.discrimination_threshold()).mark_discrimination_threshold()
Chart(mark='point', encoding=[])

mark_confusion

mark_confusion(*, normalize: str | None = None, annotate: bool = True, color_field: str = 'value', cmap: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a confusion matrix as an annotated heatmap.

Renders an ordinal heatmap with actual class on one axis and predicted class on the other. Data must carry the long-form schema emitted by ModelSource.confusion_matrix(): actual, predicted, value, value_fmt. When annotate=True, a second mark_text layer reads value_fmt for per-cell text labels.

Parameters:

Name Type Description Default
normalize ('true', 'pred', 'all')

Normalise cell counts. None (default) shows raw counts.

"true"
annotate bool

Whether to overlay per-cell count / percentage text. Default is True.

True
color_field str

Column name driving the heatmap colour scale. Default is "value".

'value'
cmap str or None

Sequential colormap name for the heat cells. None (default) defers to the theme's sequential scheme.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the rect layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for confusion-matrix rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.confusion_matrix()).mark_confusion(normalize="true")
Chart(mark='point', encoding=[])

mark_class_prediction_error

mark_class_prediction_error(*, normalize: bool = False, color_field: str = 'predicted', show_counts: bool = True, position=None, **mark_kwargs) -> 'Chart'

Render a class prediction error bar chart.

Renders one stacked bar per actual class (x-axis), with segments coloured by predicted class. This orientation surfaces which classes are confused with which — for each actual class you can see how the model's predictions distribute across the predicted classes. Data must carry long-form columns (actual, predicted, value) — same shape as ModelSource.confusion_matrix(normalize=None).

Parameters:

Name Type Description Default
normalize bool

Whether to normalise each bar to 100%. Default is False.

False
color_field str

Column driving the segment colour. Default is "predicted".

'predicted'
show_counts bool

Whether to overlay per-segment count text at the segment centre. Default is True (Schwabish SB-followup 2026-05-12). Empty segments are skipped.

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for class-prediction-error rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.confusion_matrix()).mark_class_prediction_error(normalize=True)
Chart(mark='point', encoding=[])

mark_importance

mark_importance(*, orient: str = 'horizontal', error_bars: bool = True, top_k: int | None = None, color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a feature-importance bar chart.

Renders one bar per feature, sorted descending by importance. When error_bars=True and the data carries imp_lower/imp_upper columns a second errorbar layer is added. Data must carry the schema emitted by ModelSource.importances(): feature, importance, std. The chart builder computes the bound columns and truncates to top_k rows before calling this method.

Parameters:

Name Type Description Default
orient ('horizontal', 'vertical')

Bar orientation. "horizontal" places features on the y axis with importance on x (default); "vertical" swaps axes.

"horizontal"
error_bars bool

Whether to draw error bars from imp_lower/imp_upper. Default is True.

True
top_k int or None

Limit results to the top-k features by importance. Truncation is applied by the figure-level chart builder (importance_chart); when mark_importance is called directly this parameter is forwarded to the desugar function but the desugar layer treats it as informational — actual filtering must be done on the DataFrame before passing it to Chart.

None
color_field str or None

Column name to drive per-feature colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for feature-importance rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.importances()).mark_importance(top_k=10)
Chart(mark='point', encoding=[])

mark_shap_beeswarm

mark_shap_beeswarm(*, max_display: int = 20, color_bar: bool = True, order: str = 'abs_mean', zero_line: bool = True, position=None, **mark_kwargs) -> 'Chart'

Render a SHAP beeswarm summary plot.

Visualises the distribution of SHAP values across samples for each feature as a swarm of points, coloured by the feature's original value. Data must carry the long-form schema from ModelSource.shap_values() pre-filtered to the top max_display features by the chart builder.

When zero_line=True (default) a sentinel _ref_zero column is injected and the downstream desugar appends a dashed mark_rule layer at x=0.

Parameters:

Name Type Description Default
max_display int

Maximum number of top features to show. Default is 20.

20
color_bar bool

Whether to render a colour bar for the feature-value scale. Default is True.

True
order ('abs_mean', 'mean', 'none')

Feature ordering: by mean absolute SHAP ("abs_mean"), signed mean SHAP ("mean"), or original order ("none").

"abs_mean"
zero_line bool

Whether to overlay a dashed vertical reference rule at shap_value = 0. Default is True (Schwabish SB-followup 2026-05-12).

True
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the point layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for SHAP beeswarm rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.shap_values()).mark_shap_beeswarm(max_display=15)
Chart(mark='point', encoding=[])

mark_shap_bar

mark_shap_bar(*, max_display: int = 20, position=None, **mark_kwargs) -> 'Chart'

Render a SHAP aggregated-bar feature importance chart.

Shows mean absolute SHAP values per feature as a horizontal bar chart. Data must carry the long-form schema from ModelSource.shap_values() pre-filtered to the top max_display features by the chart builder.

Parameters:

Name Type Description Default
max_display int

Maximum number of top features to show. Default is 20.

20
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New Chart configured for SHAP bar rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.shap_values()).mark_shap_bar(max_display=10)
Chart(mark='point', encoding=[])

mark_pdp

mark_pdp(*, kind: str = 'average', ice_alpha: float = 0.2, center: bool = False, color_field: str | None = 'feature', position=None, **mark_kwargs) -> 'Chart'

Render partial-dependence plots (PDP / ICE).

Visualises how the model's output varies as a function of one feature while marginalising over all others. Data must carry the long-form schema from ModelSource.partial_dependence(): feature, feature_value, pd_value. The chart builder pre-sorts ascending by feature_value.

Parameters:

Name Type Description Default
kind ('average', 'individual', 'both')

What to render. "average" draws the mean PD line; "individual" draws ICE lines (one per sample); "both" overlays average on top of ICE lines.

"average"
ice_alpha float

Opacity of individual ICE lines when kind is "individual" or "both". Default is 0.2.

0.2
center bool

Whether to centre ICE lines at their first value (centred ICE). Default is False.

False
color_field str or None

Column name driving per-feature colour. Default is "feature".

'feature'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for PDP / ICE rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.partial_dependence()).mark_pdp(kind="both", center=True)
Chart(mark='point', encoding=[])

mark_shap_waterfall

mark_shap_waterfall(*, sample_idx: int = -1, max_display: int = 20, position=None, **mark_kwargs) -> 'Chart'

Render a SHAP waterfall chart for one sample.

Shows how each feature pushes the model output from the base value toward the final prediction for a single observation. Data must carry the long-form schema from ModelSource.shap_values() for the chosen sample_idx.

Parameters:

Name Type Description Default
sample_idx int

Row index of the sample to explain. Must be provided explicitly; the default -1 is a guard sentinel that raises ValueError immediately so callers get a clear error at call time rather than at render time.

-1
max_display int

Maximum number of features to show (smallest-magnitude features are collapsed into an "other" row). Default is 20.

20
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New Chart configured for SHAP waterfall rendering.

Raises:

Type Description
ValueError

If sample_idx is not provided (left at its default of -1).

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.shap_values()).mark_shap_waterfall(sample_idx=0)
Chart(mark='point', encoding=[])

mark_learning_curve

mark_learning_curve(*, ci_style: str = 'band', color_field: str | None = 'split', position=None, **mark_kwargs) -> 'Chart'

Render a learning curve (train size vs. CV score).

Plots training set size on x against CV score on y, with separate lines for training and validation splits. Data must carry the schema emitted by ModelSource.learning_curve(), pre-deduped per (train_size, split) by the chart builder.

Parameters:

Name Type Description Default
ci_style ('band', 'bars', 'none')

How to display cross-validation variance. "band" draws a shaded ribbon; "bars" draws error bars; "none" omits CI.

"band"
color_field str or None

Column name to drive per-split line colour. Default is "split".

'split'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for learning-curve rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_train, y_train)
>>> fm.Chart(src.learning_curve()).mark_learning_curve(ci_style="band")
Chart(mark='point', encoding=[])

mark_validation_curve

mark_validation_curve(*, log_scale: bool = False, ci_style: str = 'band', color_field: str | None = 'split', param_label: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a validation curve (hyperparameter vs. CV score).

Plots a swept hyperparameter value on x against CV score on y, with separate lines for training and validation splits. Data must carry the schema emitted by ModelSource.validation_curve(), pre-deduped per (param_value, split) by the chart builder.

Parameters:

Name Type Description Default
log_scale bool

Whether to use a log scale on the x axis. Useful for parameters like regularisation strength that span orders of magnitude. Default is False.

False
ci_style ('band', 'bars', 'none')

How to display cross-validation variance.

"band"
color_field str or None

Column name to drive per-split line colour. Default is "split".

'split'
param_label str or None

Human-readable x-axis title for the hyperparameter being swept. The chart builder forwards the user's param argument here.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for validation-curve rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_train, y_train)
>>> fm.Chart(src.validation_curve(param="C")).mark_validation_curve(
...     log_scale=True, param_label="C"
... )
Chart(mark='point', encoding=[])

mark_cv_scores

mark_cv_scores(*, kind: str = 'box', split: str = 'both', position=None, **mark_kwargs) -> 'Chart'

Render a per-fold cross-validation score summary.

Shows the distribution of CV scores across folds as a box plot, strip plot, or bar chart. Data must carry the schema emitted by ModelSource.cv_scores(). The chart builder pre-aggregates per split when kind="bar" and passes raw per-fold rows for "box" or "strip".

Parameters:

Name Type Description Default
kind ('box', 'strip', 'bar')

Summary plot type.

"box"
split ('train', 'test', 'both')

Which CV split(s) to display.

"train"
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to constituent layers.

{}

Returns:

Type Description
Chart

New layered Chart configured for CV-score rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_train, y_train)
>>> fm.Chart(src.cv_scores()).mark_cv_scores(kind="strip", split="test")
Chart(mark='point', encoding=[])

mark_alpha_selection

mark_alpha_selection(*, log_scale: bool = True, highlight_best: bool = True, ci_style: str = 'band', position=None, **mark_kwargs) -> 'Chart'

Render a regularisation-strength (alpha) selection curve.

Sweeps the regularisation parameter alpha and plots CV score as a function of alpha, with variance bands. When highlight_best=True a vertical rule is drawn at the alpha that maximises mean_score. Data must carry the schema emitted by ModelSource.alpha_selection(): alpha, mean_score, score_lo, score_hi, split.

Parameters:

Name Type Description Default
log_scale bool

Whether to use a log scale on the x axis. Default is True (regularisation parameters typically span orders of magnitude).

True
highlight_best bool

Whether to draw a vertical reference rule at the optimal alpha. Default is True.

True
ci_style ('band', 'bars', 'none')

How to display CV variance.

"band"
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides forwarded to constituent layers.

{}

Returns:

Type Description
Chart

New layered Chart configured for alpha-selection rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(lasso, X_train, y_train)
>>> fm.Chart(src.alpha_selection()).mark_alpha_selection(log_scale=True)
Chart(mark='point', encoding=[])

mark_silhouette

mark_silhouette(*, zero_line: bool = True, color_field: str | None = 'cluster', position=None, **mark_kwargs) -> 'Chart'

Render a Rousseeuw silhouette plot.

Displays one horizontal bar per sample whose width encodes its silhouette coefficient, coloured by cluster assignment. Samples within each cluster are stacked vertically in descending coefficient order. Data must carry the schema emitted by ModelSource.silhouette(): sample_id, y_position, cluster, silhouette_value.

When zero_line=True a sentinel _ref_zero column is injected so the downstream mark_rule renders a single vertical rule at x=0.

The method pre-computes _silhouette_x_lo, _silhouette_x_hi, _silhouette_y_lo, and _silhouette_y_hi columns from the raw data so the renderer can draw rect marks directly.

Parameters:

Name Type Description Default
zero_line bool

Whether to draw a vertical reference rule at silhouette = 0. Default is True.

True
color_field str or None

Column name driving per-cluster colour. Default is "cluster".

'cluster'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the rect layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for silhouette rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(kmeans, X)
>>> fm.Chart(src.silhouette()).mark_silhouette()
Chart(mark='rect', encoding=[])

mark_pca_scree

mark_pca_scree(*, cumulative_line: bool = True, threshold_line: float | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a PCA scree plot.

Displays explained variance ratio per component as bars and optionally overlays the cumulative variance ratio as a line. Data must carry the schema emitted by ModelSource.pca_variance(): component, explained_variance_ratio, cumulative_variance_ratio.

When threshold_line is non-None a sentinel _threshold_line column is injected so the downstream mark_rule draws a single horizontal reference line at the threshold value.

Parameters:

Name Type Description Default
cumulative_line bool

Whether to overlay a cumulative explained variance line. Default is True.

True
threshold_line float or None

Y-position of an optional horizontal threshold reference line (e.g. 0.95 for 95% explained variance). None (default) omits the line.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for PCA scree rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(pca_model, X)
>>> fm.Chart(src.pca_variance()).mark_pca_scree(threshold_line=0.95)
Chart(mark='rect', encoding=[])

mark_intercluster_distance

mark_intercluster_distance(*, label_clusters: bool = True, color_field: str | None = 'cluster', position=None, **mark_kwargs) -> 'Chart'

Render a 2-D intercluster distance (MDS) plot.

Embeds cluster centres into 2-D using MDS and visualises each centre as a point whose area encodes cluster size. With label_clusters=True a mark_text overlay labels each point by its cluster id. Data must carry the schema emitted by ModelSource.intercluster_distance(): cluster, x, y, size.

Parameters:

Name Type Description Default
label_clusters bool

Whether to overlay cluster-id text labels. Default is True.

True
color_field str or None

Column name driving per-cluster colour. Default is "cluster".

'cluster'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the point layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for intercluster-distance rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(kmeans, X)
>>> fm.Chart(src.intercluster_distance()).mark_intercluster_distance()
Chart(mark='point', encoding=[])

mark_decision_boundary

mark_decision_boundary(*, proba: bool = False, color_field: str = 'z', position=None, **mark_kwargs) -> 'Chart'

Render a decision-boundary heatmap.

Colours a pixel grid by the model's predicted class (proba=False) or class probability (proba=True) at each grid point. Data must carry pre-computed cell bound columns x, x2, y, y2 and a prediction column z. The chart builder helper _decision_boundary_chart_from_source produces these columns from a ModelSource.

Parameters:

Name Type Description Default
proba bool

Whether to colour by predicted probability rather than class index. Default is False.

False
color_field str

Column name for the colour encoding. Default is "z".

'z'
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the rect layer.

{}

Returns:

Type Description
Chart

New Chart configured for decision-boundary rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(clf, X_test, y_test)
>>> fm.Chart(src.decision_boundary()).mark_decision_boundary(proba=True)
Chart(mark='rect', encoding=[])

mark_rank1d

mark_rank1d(*, orient: str = 'horizontal', color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a univariate feature-ranking bar chart.

Ranks features by a univariate score (e.g. mutual information, ANOVA F-statistic) and displays them as a bar chart sorted by rank. Data must carry the schema emitted by ModelSource.rank1d(): feature, score, rank.

Parameters:

Name Type Description Default
orient ('horizontal', 'vertical')

Bar orientation. "horizontal" places features on the y axis with score on x; "vertical" places features on x.

"horizontal"
color_field str or None

Column name driving per-feature colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the bar layer.

{}

Returns:

Type Description
Chart

New Chart configured for rank-1D rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.rank1d()).mark_rank1d()
Chart(mark='bar', encoding=[])

mark_rank2d

mark_rank2d(*, annot: bool = True, color_field: str = 'correlation', text_field: str = 'correlation_fmt', cmap: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a pairwise feature-ranking correlation heatmap.

Displays pairwise feature correlation scores as a colour-coded matrix. When annot=True a text overlay renders each cell's value to 2 dp. Data must carry the schema emitted by ModelSource.rank2d(): feature_x, feature_y, correlation. The chart builder appends a correlation_fmt (Utf8) column when annot=True.

Parameters:

Name Type Description Default
annot bool

Whether to overlay per-cell correlation value text. Default is True.

True
color_field str

Column driving the heatmap colour scale. Default is "correlation".

'correlation'
text_field str

Column read by the text layer. Default is "correlation_fmt".

'correlation_fmt'
cmap str or None

Diverging colormap name for correlation cells. None (default) defers to the theme's diverging scheme.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the rect layer.

{}

Returns:

Type Description
Chart

New layered Chart configured for rank-2D rendering.

Examples:

>>> import ferrum as fm
>>> src = fm.ModelSource(model, X_test, y_test)
>>> fm.Chart(src.rank2d()).mark_rank2d(annot=True)
Chart(mark='rect', encoding=[])

mark_parallel_coordinates

mark_parallel_coordinates(*, alpha: float = 0.5, color_field: str | None = None, position=None, **mark_kwargs) -> 'Chart'

Render a parallel coordinates plot.

Draws one polyline per sample across normalised feature axes. Data must carry the long-form schema produced by _parallel_coords_chart_from_dataframe: feature (Utf8), value (Float64), sample_id (Utf8), and (optionally) a hue column passed via color_field. The line layer uses mark_style.detail = "sample_id" so each sample renders as its own polyline.

Parameters:

Name Type Description Default
alpha float

Line opacity. Default is 0.5.

0.5
color_field str or None

Column name driving per-sample (or per-class) line colour.

None
position Position

Position adjustment.

None
**mark_kwargs

Mark-style overrides for the line layer.

{}

Returns:

Type Description
Chart

New Chart configured for parallel-coordinates rendering.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"feature": ["a","a","b","b"],
...                    "value": [0.5, 0.3, 0.8, 0.2],
...                    "sample_id": ["s0", "s1", "s0", "s1"]})
>>> fm.Chart(df).mark_parallel_coordinates(color_field="sample_id")
Chart(mark='line', encoding=[])

mark_arc

mark_arc(**kwargs) -> 'Chart'

Render data as arcs (pie or donut slices).

Requires Chart.coord(fm.CoordPolar(theta="x")) to be set. The theta-mapped encoding channel (x by default) determines each slice's angular sweep proportional to its value.

Parameters:

Name Type Description Default
**kwargs

Mark style overrides: color, opacity, stroke_width, etc.

{}

Examples:

>>> fm.Chart(df).mark_arc().encode(x="value", color="category").coord(
...     fm.CoordPolar(theta="x")
... )

mark_image

mark_image(**kwargs) -> 'Chart'

Render data as raster images.

Each row in the dataset becomes one image tile. Supply a base64-encoded PNG/JPEG via the url encoding channel. Requires Cartesian coordinates; returns an empty scene for Polar or Geo coord systems.

Parameters:

Name Type Description Default
**kwargs

Mark style overrides: width, height, opacity, etc.

{}

Examples:

>>> fm.Chart(df).mark_image().encode(x="x", y="y", url="data_url")

mark_geoshape

mark_geoshape(**kwargs) -> 'Chart'

Render geographic shapes from a GeoJSON FeatureCollection.

Pass a GeoJSON FeatureCollection dict to Chart(data) — ferrum auto-detects the format and splits properties into encoding channels and geometry into a __geometry__ column. Set the projection via Chart.coord(fm.CoordGeo(projection="mercator")).

Parameters:

Name Type Description Default
**kwargs

Mark style overrides: color, opacity, stroke_width, etc.

{}

Examples:

>>> fm.Chart(geojson_data).mark_geoshape().coord(
...     fm.CoordGeo(projection="equal_earth")
... )

mark_label

mark_label(**kwargs) -> 'Chart'

Render positioned text labels near data points with collision avoidance.

Each row in the dataset becomes one text label. By default the renderer uses a greedy collision-avoidance algorithm: for each label in row order it tries a ranked list of candidate offsets (above, below, right, left, diagonals) and picks the first placement whose estimated bounding box overlaps no previously-placed label. When every candidate overlaps something, the least-bad placement is chosen.

When both dx and dy are supplied explicitly, collision avoidance is bypassed and those fixed offsets are applied to every label (manual positioning path).

Parameters:

Name Type Description Default
dx float

Fixed horizontal offset in pixels. Must be combined with dy to bypass collision avoidance.

required
dy float

Fixed vertical offset in pixels. Must be combined with dx to bypass collision avoidance. Default when auto-placing is to prefer dy = -8 (above the point).

required
font_size float

Label font size in points (default 11).

required
leader_line bool

When True, a thin line is drawn from each data point to its placed label position. Useful when labels are placed far from their source points. Default False.

required
**kwargs

Additional mark style overrides (fill, opacity, font_weight, etc.).

{}

Examples:

>>> fm.Chart(df).mark_label().encode(x="x:Q", y="y:Q", text="label")
>>> fm.Chart(df).mark_label(dx=5, dy=-12).encode(x="x:Q", y="y:Q", text="label")
>>> fm.Chart(df).mark_label(leader_line=True).encode(x="x:Q", y="y:Q", text="label")

encode

encode(**channels: Any) -> 'Chart'

Set or update encoding channels on this chart.

Each keyword argument maps a channel name to a field shorthand string (e.g. "species:N") or an explicit channel object (e.g. fm.X("sepal_length", type="Q")).

Parameters:

Name Type Description Default
x str or X

Field mapped to the x position. Shorthand format: "field" (type inferred), "field:Q" (quantitative), "field:N" (nominal), "field:O" (ordinal), "field:T" (temporal), or "agg(field):Q" (aggregation).

required
y str or Y

Field mapped to the y position.

required
x2 str or X2

Secondary x position (band / segment end).

required
y2 str or Y2

Secondary y position.

required
color str or Color

Field or value driving mark colour.

required
fill str or Fill

Field or value driving mark fill colour.

required
stroke str or Stroke

Field or value driving mark stroke colour.

required
size str or Size

Field or value driving mark size.

required
shape str or Shape

Field or value driving mark shape.

required
opacity str or Opacity

Field or value driving mark opacity.

required
text str or Text

Field rendered as text labels (used with mark_text).

required
detail str or Detail

Additional grouping field that does not map to any visual property.

required
tooltip str or Tooltip

Field shown on hover.

required
**channels Any

Any other valid channel names (x_error, y_error, theta, radius, etc.).

{}

Returns:

Type Description
Chart

New Chart with updated encoding channels.

Raises:

Type Description
ValueError

If an unknown channel name is passed.

TypeError

If a value is not a string, channel instance, or Repeat placeholder.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6], "c": ["a", "b", "a"]})
>>> fm.Chart(df).mark_point().encode(x="x:Q", y="y:Q", color="c:N")
Chart(mark='point', encoding=['x', 'y', 'color'])

layer

layer(*layers) -> 'Chart'

Add one or more layer objects to this chart.

Accepts both public Layer instances (user-facing API) and internal _Layer instances (used by ferrum internals).

When a Layer(data=df, ...) has its own data attribute, that data is merged with the chart's existing data via diagonal concatenation (same strategy as the + operator). Each layer's encoding references only its own columns; null-padded rows in the merged batch are invisible to mark renderers that skip null values.

Parameters:

Name Type Description Default
*layers Layer or _Layer

Layer objects to append. Public Layer instances may carry an independent data= DataFrame.

()

Returns:

Type Description
Chart

This chart with the new layers appended.

transform

transform(*transforms) -> 'Chart'

Append one or more data transforms to the chart's pipeline.

Transforms are executed in order by the Rust engine before rendering. Multiple calls to transform() accumulate — each appends to the existing pipeline.

Parameters:

Name Type Description Default
*transforms

One or more transform objects (e.g. fm.Filter(...), fm.Aggregate(...), fm.Sort(...), fm.Window(...)). Accepts any object that serialises to a valid TransformSpec JSON shape.

()

Returns:

Type Description
Chart

New Chart with the additional transforms appended.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> fm.Chart(df).mark_point().encode(x="x", y="y").transform(
...     fm.Filter("datum.x > 1")
... )
Chart(mark='point', encoding=['x', 'y'])

facet

facet(field: Optional[str] = None, *, row: Optional[str] = None, col: Optional[str] = None, ncols: Optional[int] = None, nrows: Optional[int] = None) -> 'Chart'

Facet this chart into small multiples by a field.

Two modes are supported:

  • Wrap — a single field is wrapped across columns (rows auto). Pass field= or equivalently col= alone.
  • Grid — two fields define row × column layout. Pass both row= and col=.

Parameters:

Name Type Description Default
field str

Column name used for wrap-mode faceting. Mutually exclusive with using both row and col together.

None
row str

Column name for the row dimension (grid mode). When used alone, behaves as wrap mode on the row axis.

None
col str

Column name for the column dimension (wrap or grid mode).

None
ncols int or None

Maximum number of columns in wrap mode. None lets the renderer choose.

None
nrows int or None

Maximum number of rows. None lets the renderer choose.

None

Returns:

Type Description
Chart

New Chart with faceting configured.

Raises:

Type Description
ValueError

If neither field, row, nor col is provided.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1,2,3]*3, "y": [4,5,6]*3,
...                    "g": ["a","a","b","b","c","c","a","b","c"]})
>>> fm.Chart(df).mark_point().encode(x="x", y="y").facet(col="g", ncols=2)
Chart(mark='point', encoding=['x', 'y'])

theme

theme(theme: Any) -> 'Chart'

Attach a Theme to this chart, overriding the process-level default.

Per-chart theme always wins over ferrum.set_default_theme(). Theme objects are immutable value classes — modifying the original Theme after calling .theme() has no effect on the chart.

Parameters:

Name Type Description Default
theme Theme

A ferrum.Theme instance (e.g. fm.themes.dark(), fm.Theme(background="white", font="serif")).

required

Returns:

Type Description
Chart

New Chart with the specified theme attached.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> dark = fm.themes.dark()
>>> fm.Chart(df).mark_point().encode(x="x", y="y").theme(dark)
Chart(mark='point', encoding=['x', 'y'])

axis

axis(*, x: Optional[bool] = None, y: Optional[bool] = None, show: Optional[bool] = None) -> 'Chart'

Suppress (or restore) the chart's x/y axis decorations.

Spec-level axis suppression — when x=False (or y=False), the corresponding axis line, ticks, tick labels, and axis title are omitted at layout time. The plot area's pixel rect is unchanged (gutters reserved for axis decorations are preserved), so this method is intended for sub-charts whose axes are shared with a neighbouring chart in a compound view: clustermap dendrograms, JointChart marginals, RepeatChart off-diagonal panels.

Parameters:

Name Type Description Default
x bool

False hides the x axis; True shows it; None leaves the current setting (default visible).

None
y bool

False hides the y axis; True shows it; None leaves the current setting (default visible).

None
show bool

Shorthand for axis(x=show, y=show). Mutually exclusive with per-axis x/y arguments.

None

Returns:

Type Description
Chart

New Chart with the requested axis-visibility settings.

Raises:

Type Description
ValueError

If show is combined with x or y.

Examples:

Hide both axes (e.g. for a dendrogram panel):

>>> chart.axis(show=False)

Hide just the x axis (top marginal of a JointChart):

>>> chart.axis(x=False)

coord

coord(coord: Any) -> 'Chart'

Set the coordinate system for this chart.

Currently only CoordFlip is supported (swaps x and y axes).

Parameters:

Name Type Description Default
coord CoordFlip

A coordinate-system object. Pass fm.CoordFlip() to swap the horizontal and vertical axes.

required

Returns:

Type Description
Chart

New Chart with the coordinate system set.

Raises:

Type Description
TypeError

If coord is not a supported coordinate-system type.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"cat": ["a", "b", "c"], "val": [10, 20, 15]})
>>> fm.Chart(df).mark_bar().encode(x="cat", y="val").coord(fm.CoordFlip())
Chart(mark='bar', encoding=['x', 'y'])

properties

properties(*, width=None, height=None, title=None, description=None, render_config=None) -> 'Chart'

Set chart-level display properties.

Only the keyword arguments that are explicitly provided are updated; unset properties inherit from the existing chart.

Parameters:

Name Type Description Default
width int or 'container' or None

Chart width in pixels, or "container" to fill the parent.

None
height int or 'container' or None

Chart height in pixels.

None
title str or None

Chart title rendered above the plot area.

None
description str or None

Accessible description attached to the SVG root.

None
render_config RenderConfig or None

Rendering policy configuration. Controls auto-raster threshold and behavior. For one-off overrides prefer the raster= keyword on .show() / .save() / .show_svg() instead.

None

Returns:

Type Description
Chart

New Chart with the specified properties updated.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4]})
>>> fm.Chart(df).mark_point().encode(x="x", y="y").properties(
...     width=400, height=300, title="My Chart"
... )
Chart(mark='point', encoding=['x', 'y'])

to_spec

to_spec()

Build the Rust ChartSpec for this chart.

Resolves any pending statistical-mark desugar, converts Python encoding channel objects to EncodingSpec instances, and constructs the ChartSpec PyO3 object that the Rust renderer consumes.

Returns:

Type Description
ChartSpec

The fully-resolved ferrum._core.ChartSpec for this chart.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4]})
>>> spec = fm.Chart(df).mark_point().encode(x="x", y="y").to_spec()
>>> spec.mark
'point'

to_json

to_json(*, indent=None) -> str

Serialise the chart specification to a JSON string.

Calls to_spec() to build the ChartSpec and then serialises it via the Rust serde_json encoder. When indent is given the compact JSON is reformatted via json.loads / json.dumps on the Python side (the Rust encoder always produces compact output).

Parameters:

Name Type Description Default
indent int or None

Number of spaces to use for pretty-printing. None (default) returns compact single-line JSON.

None

Returns:

Type Description
str

JSON representation of the chart specification.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1], "y": [2]})
>>> spec_json = fm.Chart(df).mark_point().encode(x="x", y="y").to_json()
>>> '"mark"' in spec_json
True

add_selection

add_selection(*selections) -> 'Chart'

Attach interactive selection(s) to this chart.

Per ferrum-spec.md §3.10 (L736), the SVG/PNG renderer silently ignores selections — they are intended for the WASM renderer (Phase 11). This method accepts any number of selection objects and returns a new Chart unchanged so that user code building selection-aware charts remains forward-compatible without raising under SVG/PNG rendering.

Parameters:

Name Type Description Default
*selections

Any number of selection objects (currently ignored).

()

Returns:

Type Description
Chart

New Chart (clone), with the selections recorded but not rendered.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4]})
>>> chart = fm.Chart(df).mark_point().encode(x="x", y="y").add_selection()

interactive

interactive() -> 'Chart'

Mark this chart as interactive.

Per ferrum-spec.md §3.10 (L736), interactive features (selections, pan/zoom, conditional encodings) are silently ignored under SVG/PNG. Returns a new Chart so chained construction patterns work today and will gain real interactivity once the Phase 11 WASM renderer ships.

Returns:

Type Description
Chart

New Chart (clone).

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4]})
>>> chart = fm.Chart(df).mark_point().encode(x="x", y="y").interactive()

conditional

conditional(spec: Any) -> 'Chart'

Apply a conditional encoding to this chart.

Convenience sugar: chart.conditional(sel.when(Color("x")).otherwise(value("#ccc"))) is equivalent to::

chart.add_selection(sel).encode(color=sel.when(Color("x")).otherwise(value("#ccc")))

Parameters:

Name Type Description Default
spec ConditionalSpec

A ConditionalSpec produced by sel.when(...).otherwise(...).

required

Returns:

Type Description
Chart

New Chart with the conditional recorded.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> from ferrum.selection import selection_point, value
>>> df = pl.DataFrame({"x": [1, 2], "y": [3, 4], "z": ["a", "b"]})
>>> sel = selection_point(fields=["z"])
>>> chart = (
...     fm.Chart(df)
...     .mark_point()
...     .encode(x="x", y="y")
...     .conditional(sel.when(fm.Color("z")).otherwise(value("#ccc")))
... )

RenderConfig dataclass

Per-chart rendering configuration.

Controls the auto-raster policy that transparently substitutes mark_raster for per-element marks when the mark count exceeds raster_threshold. This prevents multi-million-row charts from producing impractically large SVG output.

For one-off overrides, prefer the raster= keyword on output methods (chart.show(raster=False), chart.save(..., raster=False), chart.show_svg(raster=False)). Use RenderConfig when you want to bake the policy into the chart object itself.

Parameters:

Name Type Description Default
raster_threshold int or None

Mark count above which auto-raster fires. None disables auto-raster entirely.

500_000
raster_behavior ('warn', 'silent', 'error')

"warn" emits a UserWarning when auto-raster substitutes. "silent" substitutes without warning. "error" raises ValueError instead of substituting.

"warn"
raster_aggregate str

Aggregation function for the substituted mark_raster.

"count"
raster_cmap str

Colormap for the substituted mark_raster.

"viridis"

Identity

Explicit no-op position adjustment.

Distinct from position=None (which means "no adjustment declared"): Identity is part of the spec and round-trips through JSON. Use it when composing layered charts that need to opt out of an inherited stack or dodge on a per-layer basis.

Eligible marks: all.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="grp", y="val").mark_bar(position=fm.Identity())

to_spec_dict

to_spec_dict() -> dict

Return the spec dict {"type": "identity"}.

Dodge

Side-by-side placement of marks grouped by a channel.

Eligible marks: bar, point, box, boxplot, boxen, swarm, violin, errorbar, errorband, ribbon, histogram, density.

Parameters:

Name Type Description Default
by str

Channel name to group by. Defaults to the color/fill channel when omitted.

None
padding float

Gap between dodged groups as a fraction of band width. Must be in [0, 1).

0.05

Raises:

Type Description
ValueError

If padding is outside [0, 1).

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="cat", y="val", color="grp").mark_bar(
...     position=fm.Dodge()
... )

to_spec_dict

to_spec_dict() -> dict

Return the serialized spec dict for this position adjustment.

Jitter

Random per-row noise applied to x, y, or both axes.

Uses a ChaCha8 RNG seeded from seed, making SVG output byte-deterministic for a given dataset and seed. When seed=None the Rust renderer derives a per-row seed from the row's data values via xxh3 — output remains deterministic across runs for fixed inputs.

Eligible marks: point, swarm, tick.

Parameters:

Name Type Description Default
axis ('x', 'y', 'both')

Which axis or axes to jitter.

"x"
width float

Maximum absolute displacement in scaled units. Must be > 0.

0.4
seed int or None

RNG seed. None means per-row data-derived seed (still deterministic).

None

Raises:

Type Description
ValueError

If axis is not one of "x", "y", "both".

ValueError

If width is <= 0.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="grp", y="value").mark_point(
...     position=fm.Jitter(width=0.3, seed=42)
... )

to_spec_dict

to_spec_dict() -> dict

Return the serialized spec dict for this position adjustment.

Stack

Vertical accumulation of marks grouped by a channel.

Eligible marks: rect-style (bar, area, ribbon, histogram, density) and annotation-style (text, point, rule, tick). The latter sit on top of a stacked layer to label segments.

Parameters:

Name Type Description Default
by str

Channel name whose distinct values define the stack groups. Defaults to the color/fill channel when omitted.

None
offset ('zero', 'normalize', 'center')

Stack baseline strategy:

  • "zero" — standard cumulative stack from y = 0.
  • "normalize" — 100 % stack; each x-bin scales to a total of 1.
  • "center" — streamgraph; symmetric around y = 0.
"zero"
anchor ('top', 'mid')

Where each row's y output lands within its segment. "top" (default) returns the segment top so rect-style marks (bar, area, ribbon) draw from __stack_y_base__ to y. "mid" returns the segment midpoint so an annotation mark (mark_text, mark_point, …) sits at the visual centre of each stacked segment — used by composite marks like mark_class_prediction_error(show_counts=True) to land per-segment count labels without duplicating cumsum logic in Python.

"top"

Raises:

Type Description
ValueError

If offset is not one of "zero", "normalize", "center" or anchor is not one of "top", "mid".

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="year", y="count", color="category").mark_bar(
...     position=fm.Stack(offset="normalize")
... )

to_spec_dict

to_spec_dict() -> dict

Return the serialized spec dict for this position adjustment.

CoordFlip dataclass

Flip the x and y axes — e.g. for horizontal bar charts.

Pass to Chart.coord(CoordFlip()).

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="value", y="category").mark_bar().coord(
...     fm.CoordFlip()
... )

to_spec_dict

to_spec_dict() -> str

Return the string token passed to ChartSpec coord param.

CoordCartesian dataclass

Standard Cartesian coordinates with optional domain and clip overrides.

Parameters:

Name Type Description Default
xlim (float, float) | None

Explicit x-axis domain (min, max). None uses data extent.

None
ylim (float, float) | None

Explicit y-axis domain (min, max). None uses data extent.

None
expand bool

Add padding around the data extent (default True).

True
clip bool

Clip marks to the plot area (default True).

True

Examples:

>>> fm.Chart(df).mark_point().encode(x="x", y="y").coord(
...     fm.CoordCartesian(xlim=(0, 100))
... )

to_spec_dict

to_spec_dict() -> dict

Return dict serialization for ChartSpec coord param.

CoordPolar dataclass

Polar coordinates for pie and radial charts.

The theta parameter names which encoding channel ("x" or "y") is interpreted as the angular variable. The other channel is used as the radial variable (for scatter-in-polar mode); omit it for pie/donut charts.

Parameters:

Name Type Description Default
theta ('x', 'y')

Which encoding channel maps to the angle.

"x"
start float

Starting angle in radians (default 0 = 12 o'clock).

0.0
direction (1, -1)

1 for clockwise, -1 for counter-clockwise.

1
inner_radius float

Inner radius in pixels. 0 (default) gives a filled pie slice; any positive value creates a donut with a hole of that radius.

0.0
outer_radius float or None

Outer radius in pixels. None (default) fills to half the smaller panel dimension.

None
pad_angle float

Angular gap between adjacent slices in radians (default 0).

0.0

Examples:

Pie chart::

fm.Chart(df).mark_arc().encode(x="value", color="category").coord(
    fm.CoordPolar(theta="x")
)

Donut with 60 px hole::

fm.Chart(df).mark_arc().encode(x="value", color="category").coord(
    fm.CoordPolar(theta="x", inner_radius=60)
)

to_spec_dict

to_spec_dict() -> dict

Return dict serialization for ChartSpec coord param.

CoordGeo dataclass

Geographic map-projection coordinates.

Parameters:

Name Type Description Default
projection str

One of "mercator", "albers_usa", "equal_earth", "natural_earth", "orthographic", "equirectangular".

'mercator'

Examples:

>>> fm.Chart(geojson_df).mark_geoshape().coord(
...     fm.CoordGeo(projection="equal_earth")
... )

to_spec_dict

to_spec_dict() -> dict

Return dict serialization for ChartSpec coord param.

CoordFixed dataclass

Cartesian coordinates with a fixed aspect ratio.

Parameters:

Name Type Description Default
ratio float

Width-to-height ratio of one data unit. 1.0 makes the plot square in data space.

1.0
xlim (float, float) | None

Explicit x-axis domain.

None
ylim (float, float) | None

Explicit y-axis domain.

None
expand bool

Add padding around data extent (default True).

True
clip bool

Clip marks to plot area (default True).

True

Examples:

>>> fm.Chart(df).mark_point().encode(x="x", y="y").coord(
...     fm.CoordFixed(ratio=1.0)
... )

to_spec_dict

to_spec_dict() -> dict

Return dict serialization for ChartSpec coord param.

Layer

Single rendering layer inside a multi-layer Chart.

Most multi-layer charts are built via the + operator on two Chart instances (chart1 + chart2). Direct construction of Layer objects is rarely needed outside of ferrum internals and composite-mark expansion code.

Parameters:

Name Type Description Default
data object

DataFrame or Arrow-compatible object for this layer. When None the layer inherits data from the parent ChartSpec.

None
mark str or MarkSpec

Mark type string (e.g. "point", "line") or a MarkSpec object.

None
encoding dict

Mapping of channel names to ChannelBase objects. Defaults to an empty dict when omitted.

None
transforms list

Sequence of transform objects applied to this layer's data before rendering. Defaults to an empty list when omitted.

None
mark_kwargs dict

Extra keyword arguments forwarded to the mark renderer (e.g. {"dx": 5, "opacity": 0.7}).

None

Examples:

>>> from ferrum.layer import Layer
>>> layer = Layer(mark="text", encoding={"x": "x", "y": "y"}, mark_kwargs={"dx": 5})

HConcatChart

Bases: _CompositeBase

Horizontal concatenation of two or more charts.

Each sub-chart retains its own scales, axes, and legend. Construct via the | operator on Chart instances or directly with a list.

Parameters:

Name Type Description Default
charts list of Chart

Sub-charts to concatenate left-to-right.

required
spacing float

Horizontal pixel gap between adjacent charts.

10.0

Examples:

>>> import ferrum as fm
>>> combined = fm.Chart(df).encode(x="hp", y="mpg").mark_point() | fm.Chart(df).encode(x="hp").mark_histogram()
>>> combined.save("side_by_side.svg")

show

show() -> None

Print the SVG markup to stdout.

show_png

show_png() -> bytes

Render to PNG bytes (2x retina by default).

Rasterises the SVG produced by show_svg() through the Rust resvg pipeline -- the same rasteriser Chart.show_png() uses, with the same 2x default scale.

Returns:

Type Description
bytes

PNG image as raw bytes suitable for IPython.display.Image or writing directly to disk.

save

save(path: str, *, format=None, **kwargs) -> None

Save the composition to a file.

Parameters:

Name Type Description Default
path str

Destination file path. The extension determines the format when format is omitted.

required
format str

"svg" or "png". Other formats raise NotImplementedError.

None

Raises:

Type Description
NotImplementedError

If format is not "svg" or "png".

share_scale

share_scale(**channels)

Share scales across this composition's member charts.

Computes the union domain for each channel marked "shared" and re-emits every member chart with an explicit scale= dict on that channel, so the participating axes lock to the same ticks. Channels marked "independent" (the default for any channel not listed) keep their per-chart domains.

Parameters:

Name Type Description Default
**channels str

Channel name → "shared" | "independent". Common channels: x, y, color, size.

{}

Returns:

Type Description
_ChartLike

A new composition of the same type with the shared scales injected. No-op (returns self) when no channel is "shared" or none of the requested channels are bound on any member chart.

Raises:

Type Description
ValueError

If any value is not "shared" or "independent".

Examples:

>>> import ferrum as fm
>>> combined = (chart_a | chart_b).share_scale(x="shared")
>>> grid = fm.JointChart(center, top=hist_x, right=hist_y).share_scale(y="shared")

theme

theme(t)

Apply a theme to every sub-chart and return a new composition.

Parameters:

Name Type Description Default
t Theme

Theme value to apply.

required

Returns:

Type Description
_ChartLike

A new instance of the same composition class with t applied to each sub-chart.

properties

properties(**kwargs)

Forward properties(**kwargs) to every sub-chart.

Parameters:

Name Type Description Default
**kwargs

Keyword arguments accepted by Chart.properties (e.g. width, height, title, background).

{}

Returns:

Type Description
_ChartLike

A new instance of the same composition class with updated sub-chart properties.

show_svg

show_svg() -> str

Render the horizontally concatenated charts to an SVG string.

Returns:

Type Description
str

SVG markup with sub-charts placed left-to-right.

VConcatChart

Bases: _CompositeBase

Vertical concatenation of two or more charts.

Each sub-chart retains its own scales, axes, and legend. Construct via the & operator on Chart instances or directly with a list.

Parameters:

Name Type Description Default
charts list of Chart

Sub-charts to stack top-to-bottom.

required
spacing float

Vertical pixel gap between adjacent charts.

10.0

Examples:

>>> import ferrum as fm
>>> stacked = fm.Chart(df).encode(x="hp", y="mpg").mark_point() & fm.Chart(df).encode(x="hp").mark_histogram()
>>> stacked.save("stacked.svg")

show

show() -> None

Print the SVG markup to stdout.

show_png

show_png() -> bytes

Render to PNG bytes (2x retina by default).

Rasterises the SVG produced by show_svg() through the Rust resvg pipeline -- the same rasteriser Chart.show_png() uses, with the same 2x default scale.

Returns:

Type Description
bytes

PNG image as raw bytes suitable for IPython.display.Image or writing directly to disk.

save

save(path: str, *, format=None, **kwargs) -> None

Save the composition to a file.

Parameters:

Name Type Description Default
path str

Destination file path. The extension determines the format when format is omitted.

required
format str

"svg" or "png". Other formats raise NotImplementedError.

None

Raises:

Type Description
NotImplementedError

If format is not "svg" or "png".

share_scale

share_scale(**channels)

Share scales across this composition's member charts.

Computes the union domain for each channel marked "shared" and re-emits every member chart with an explicit scale= dict on that channel, so the participating axes lock to the same ticks. Channels marked "independent" (the default for any channel not listed) keep their per-chart domains.

Parameters:

Name Type Description Default
**channels str

Channel name → "shared" | "independent". Common channels: x, y, color, size.

{}

Returns:

Type Description
_ChartLike

A new composition of the same type with the shared scales injected. No-op (returns self) when no channel is "shared" or none of the requested channels are bound on any member chart.

Raises:

Type Description
ValueError

If any value is not "shared" or "independent".

Examples:

>>> import ferrum as fm
>>> combined = (chart_a | chart_b).share_scale(x="shared")
>>> grid = fm.JointChart(center, top=hist_x, right=hist_y).share_scale(y="shared")

theme

theme(t)

Apply a theme to every sub-chart and return a new composition.

Parameters:

Name Type Description Default
t Theme

Theme value to apply.

required

Returns:

Type Description
_ChartLike

A new instance of the same composition class with t applied to each sub-chart.

properties

properties(**kwargs)

Forward properties(**kwargs) to every sub-chart.

Parameters:

Name Type Description Default
**kwargs

Keyword arguments accepted by Chart.properties (e.g. width, height, title, background).

{}

Returns:

Type Description
_ChartLike

A new instance of the same composition class with updated sub-chart properties.

show_svg

show_svg() -> str

Render the vertically concatenated charts to an SVG string.

Returns:

Type Description
str

SVG markup with sub-charts stacked top-to-bottom.

JointChart

Bases: _ChartLike

Joint distribution view: center chart plus optional top and right marginals.

Lays out a 2 × 2 grid: center chart occupies the bottom-left cell, top marginal goes top-left, right marginal goes bottom-right, and the top-right corner is empty. The x-axis is shared between the center and top charts; the y-axis is shared between the center and right charts.

The cell size ratio between the center and each marginal is controlled by ratio. A ratio of 5 gives the center 5/(5+1) of each dimension and each marginal 1/(5+1).

Most users obtain a JointChart from ferrum.jointplot rather than constructing one directly.

Parameters:

Name Type Description Default
center Chart

Primary scatter / distribution chart occupying the main panel.

required
top Chart

Marginal chart drawn above the center (e.g. a histogram of the x variable).

None
right Chart

Marginal chart drawn to the right of the center (e.g. a histogram of the y variable).

None
ratio int

Size ratio of the center panel to each marginal panel. Must be > 0.

5
spacing float

Pixel gap between adjacent cells.

10.0

Raises:

Type Description
ValueError

If ratio is not > 0.

Examples:

>>> import ferrum as fm
>>> joint = fm.jointplot(df, x="hp", y="mpg")
>>> joint.save("joint.svg")

charts property

charts: list

List of Chart : All non-None sub-charts (center, top, right).

spec property

spec: dict

Dict : Serializable layout spec consumed by the SVG compositor.

show

show() -> None

Print the SVG markup to stdout.

show_png

show_png() -> bytes

Render to PNG bytes (2x retina by default).

Rasterises the SVG produced by show_svg() through the Rust resvg pipeline -- the same rasteriser Chart.show_png() uses, with the same 2x default scale.

Returns:

Type Description
bytes

PNG image as raw bytes suitable for IPython.display.Image or writing directly to disk.

save

save(path: str, *, format=None, **kwargs) -> None

Save the composition to a file.

Parameters:

Name Type Description Default
path str

Destination file path. The extension determines the format when format is omitted.

required
format str

"svg" or "png". Other formats raise NotImplementedError.

None

Raises:

Type Description
NotImplementedError

If format is not "svg" or "png".

share_scale

share_scale(**channels)

Share scales across this composition's member charts.

Computes the union domain for each channel marked "shared" and re-emits every member chart with an explicit scale= dict on that channel, so the participating axes lock to the same ticks. Channels marked "independent" (the default for any channel not listed) keep their per-chart domains.

Parameters:

Name Type Description Default
**channels str

Channel name → "shared" | "independent". Common channels: x, y, color, size.

{}

Returns:

Type Description
_ChartLike

A new composition of the same type with the shared scales injected. No-op (returns self) when no channel is "shared" or none of the requested channels are bound on any member chart.

Raises:

Type Description
ValueError

If any value is not "shared" or "independent".

Examples:

>>> import ferrum as fm
>>> combined = (chart_a | chart_b).share_scale(x="shared")
>>> grid = fm.JointChart(center, top=hist_x, right=hist_y).share_scale(y="shared")

theme

theme(t)

Apply a theme to every sub-chart and return a new composition.

Parameters:

Name Type Description Default
t Theme

Theme value to apply.

required

Returns:

Type Description
_ChartLike

A new instance of the same composition class with t applied to each sub-chart.

properties

properties(**kwargs)

Forward properties(**kwargs) to the center chart.

The marginals (top, right) are kept unchanged because their width / height is derived from the center plus ratio at render time.

Parameters:

Name Type Description Default
**kwargs

Keyword arguments accepted by Chart.properties (e.g. width, height, title).

{}

Returns:

Type Description
JointChart

A new instance with updated center-chart properties.

show_svg

show_svg() -> str

Render the joint chart to an SVG string.

Returns:

Type Description
str

SVG markup with the 2 × 2 grid layout.

RepeatChart

Bases: _ChartLike

Repeat a template chart over a grid of row / column field combinations.

Use Repeat.column, Repeat.row, or Repeat.layer typed sentinels in the template's .encode(...) call to mark which encoding channel receives the per-cell field substitution. RepeatChart.expand() materializes the grid into fully-resolved (row_field, col_field, Chart) tuples.

diagonal= provides an alternate template for cells where row_field == col_field (symmetric n × n repeat). corner=True filters the expanded grid to the lower triangle including the diagonal.

Most users obtain a RepeatChart through Chart.repeat() or ferrum.pairplot.

Parameters:

Name Type Description Default
template Chart

Template chart whose Repeat.* placeholders are substituted per cell.

required
row list of str

Field names assigned to the row axis.

None
column list of str

Field names assigned to the column axis.

None
layer list of str

Field names assigned to the layer axis (for non-grid repeat layouts).

None
diagonal Chart

Alternate template used when row_field == col_field. Requires both row and column to be set.

None
corner bool

When True, only the lower-triangle cells (ri >= ci) are rendered, giving a half-matrix layout.

False
spacing float

Pixel gap between adjacent cells.

10.0
columns int

Maximum number of columns for a wrapped 1-D repeat layout (no-op for 2-D row/column repeat).

None
resolve dict

Per-channel scale-sharing overrides — e.g. resolve={"x": "shared", "y": "independent"}. "shared" computes the union domain across all cells (and across every layer of layered cells) and injects an explicit scale on every participating chart so the axis ticks match. "independent" (the default for unlisted channels) keeps per-cell domains.

None

Raises:

Type Description
ValueError

If diagonal is set but row or column is not.

Examples:

>>> import ferrum as fm
>>> base = fm.Chart(df).encode(x=fm.Repeat.column, y=fm.Repeat.row).mark_point()
>>> grid = fm.RepeatChart(base, row=["mpg", "hp"], column=["mpg", "hp"])
>>> grid.save("pair_grid.svg")

charts property

charts: list

List of Chart : Template plus diagonal (when set), in init order.

spec property

spec: dict

Dict : Serializable layout spec consumed by the SVG compositor.

show

show() -> None

Print the SVG markup to stdout.

show_png

show_png() -> bytes

Render to PNG bytes (2x retina by default).

Rasterises the SVG produced by show_svg() through the Rust resvg pipeline -- the same rasteriser Chart.show_png() uses, with the same 2x default scale.

Returns:

Type Description
bytes

PNG image as raw bytes suitable for IPython.display.Image or writing directly to disk.

save

save(path: str, *, format=None, **kwargs) -> None

Save the composition to a file.

Parameters:

Name Type Description Default
path str

Destination file path. The extension determines the format when format is omitted.

required
format str

"svg" or "png". Other formats raise NotImplementedError.

None

Raises:

Type Description
NotImplementedError

If format is not "svg" or "png".

theme

theme(t)

Apply a theme to every sub-chart and return a new composition.

Parameters:

Name Type Description Default
t Theme

Theme value to apply.

required

Returns:

Type Description
_ChartLike

A new instance of the same composition class with t applied to each sub-chart.

properties

properties(**kwargs)

Forward properties(**kwargs) to every sub-chart.

Parameters:

Name Type Description Default
**kwargs

Keyword arguments accepted by Chart.properties (e.g. width, height, title, background).

{}

Returns:

Type Description
_ChartLike

A new instance of the same composition class with updated sub-chart properties.

expand

expand() -> list

Materialize the template into fully-resolved chart cells.

Cell iteration shape:

  • 2-D grid (both row and column set): len(row) × len(column) cells, optionally filtered by corner; diagonal substitutes the template on row_field == col_field cells.
  • 1-D wrap (only one of row or column set): the populated field list, paired with None on the missing axis. Geometry is applied by :meth:show_svg driven by columns.
  • Layer-only (layer= set, row and column both None): a single cell containing all layers.

When layer= is set, each cell becomes a layered Chart with one layer per element in self.layer (substituted into every Repeat.layer placeholder). Diagonal cells skip layering — the diagonal template already defines that cell.

Returns:

Type Description
list of tuple

Each element is (row_field, col_field, Chart) with all Repeat.* placeholders replaced. For 1-D and layer-only layouts the unused axis is None.

Raises:

Type Description
ValueError

If diagonal is set but row != column (asymmetric repeat), or if the template references a Repeat.* placeholder for an axis that was not populated.

share_scale

share_scale(**channels)

Share scales across this repeat's cells by merging into resolve=.

Equivalent to constructing the chart with resolve={...} set — both paths run through :meth:_apply_resolve at expand() time, so the union-domain computation sees every cell (including each layer of layered cells) exactly once. Passing the same channel twice with different modes takes the call's value.

Parameters:

Name Type Description Default
**channels str

Channel name → "shared" | "independent".

{}

Returns:

Type Description
RepeatChart

A new RepeatChart with the merged resolve= config.

show_svg

show_svg() -> str

Render the repeated grid to an SVG string.

Returns:

Type Description
str

SVG markup containing all materialized cell charts in a grid.

Notes

2-D grids (both row and column set) lay out as len(row) × len(column). 1-D layouts (only one axis set) wrap by columns — column-only spreads left-to-right and wraps downward; row-only spreads top-to-bottom in a single column unless columns opens additional columns. When columns is unset the 1-D layout is a single row (column-only) or column (row-only).

ClusterMapChart

Bases: _ChartLike

Clustered heatmap with optional row and column dendrograms.

Lays out a 2 × 2 grid: the heatmap occupies the bottom-right cell, the column dendrogram goes top-right, the row dendrogram (rotated 90°) goes bottom-left, and the top-left corner is empty. Dendrogram value axes are hidden; categorical axes align with the heatmap row/column labels.

Cell size is split by dendrogram_ratio: dendrograms receive that fraction of the total width/height, the heatmap receives the remainder.

Most users obtain a ClusterMapChart from ferrum.clustermap rather than constructing one directly.

Parameters:

Name Type Description Default
heatmap Chart

The central heatmap chart.

required
row_dendrogram Chart

Dendrogram chart for the row axis. Displayed to the left of the heatmap, rotated 90°.

None
col_dendrogram Chart

Dendrogram chart for the column axis. Displayed above the heatmap.

None
dendrogram_ratio float

Fraction of the total width/height allocated to each dendrogram panel. Must be in the open interval (0, 1).

0.2
spacing float

Pixel gap between adjacent cells.

10.0

Raises:

Type Description
ValueError

If dendrogram_ratio is not in the open interval (0, 1).

Examples:

>>> import ferrum as fm
>>> cm = fm.clustermap(df, method="ward", cmap="rdbu")
>>> cm.save("clustermap.svg")

charts property

charts: list

List of Chart : All non-None sub-charts in __init__ order (heatmap, row_dendrogram, col_dendrogram).

spec property

spec: dict

Dict : Serializable layout spec consumed by the SVG compositor.

show

show() -> None

Print the SVG markup to stdout.

show_png

show_png() -> bytes

Render to PNG bytes (2x retina by default).

Rasterises the SVG produced by show_svg() through the Rust resvg pipeline -- the same rasteriser Chart.show_png() uses, with the same 2x default scale.

Returns:

Type Description
bytes

PNG image as raw bytes suitable for IPython.display.Image or writing directly to disk.

save

save(path: str, *, format=None, **kwargs) -> None

Save the composition to a file.

Parameters:

Name Type Description Default
path str

Destination file path. The extension determines the format when format is omitted.

required
format str

"svg" or "png". Other formats raise NotImplementedError.

None

Raises:

Type Description
NotImplementedError

If format is not "svg" or "png".

share_scale

share_scale(**channels)

Share scales across this composition's member charts.

Computes the union domain for each channel marked "shared" and re-emits every member chart with an explicit scale= dict on that channel, so the participating axes lock to the same ticks. Channels marked "independent" (the default for any channel not listed) keep their per-chart domains.

Parameters:

Name Type Description Default
**channels str

Channel name → "shared" | "independent". Common channels: x, y, color, size.

{}

Returns:

Type Description
_ChartLike

A new composition of the same type with the shared scales injected. No-op (returns self) when no channel is "shared" or none of the requested channels are bound on any member chart.

Raises:

Type Description
ValueError

If any value is not "shared" or "independent".

Examples:

>>> import ferrum as fm
>>> combined = (chart_a | chart_b).share_scale(x="shared")
>>> grid = fm.JointChart(center, top=hist_x, right=hist_y).share_scale(y="shared")

theme

theme(t)

Apply a theme to every sub-chart and return a new composition.

Parameters:

Name Type Description Default
t Theme

Theme value to apply.

required

Returns:

Type Description
_ChartLike

A new instance of the same composition class with t applied to each sub-chart.

properties

properties(**kwargs)

Forward properties(**kwargs) to the heatmap chart.

The dendrogram panels are kept unchanged because their width / height is derived from the heatmap plus dendrogram_ratio at render time.

Parameters:

Name Type Description Default
**kwargs

Keyword arguments accepted by Chart.properties (e.g. width, height, title).

{}

Returns:

Type Description
ClusterMapChart

A new instance with updated heatmap-chart properties.

show_svg

show_svg() -> str

Render the cluster map to an SVG string.

Returns:

Type Description
str

SVG markup with the 2 × 2 grid layout.

Repeat

Namespace for typed RepeatChart template sentinels.

Access the three sentinels via class attributes — do not instantiate Repeat directly:

Attributes:

Name Type Description
column _RepeatPlaceholder

Sentinel that resolves to the column-axis field for each cell.

row _RepeatPlaceholder

Sentinel that resolves to the row-axis field for each cell.

layer _RepeatPlaceholder

Sentinel that resolves to the layer-axis field for each cell.

Examples:

>>> import ferrum as fm
>>> base = (
...     fm.Chart(df)
...     .encode(x=fm.Repeat.column, y=fm.Repeat.row)
...     .mark_point()
... )
>>> grid = fm.RepeatChart(base, row=["mpg", "hp"], column=["mpg", "hp"])

AUCLabel dataclass

Auto-placed AUC annotation for ROC charts.

chart + AUCLabel() reads the surrounding chart's line data (x = FPR, y = TPR), computes trapezoidal AUC per series (grouped by color when present), and emits one text annotation per series at the line endpoint.

Parameters:

Name Type Description Default
position ('end', 'corner')

Where to place the label. "end" puts it at the rightmost point of each series curve; "corner" anchors it near the top-right of the plot area.

"end"
format str

Python format spec applied to the AUC value (e.g. ".2f" for two decimal places).

".3f"
prefix str

Text prepended to the formatted metric value.

"AUC = "

Examples:

>>> import ferrum as fm
>>> chart = fm.roc_chart(model, X_test, y_test)
>>> annotated = chart + fm.AUCLabel()

APLabel dataclass

Auto-placed Average Precision annotation for PR charts.

Sibling of :class:AUCLabel for precision-recall curves. x is treated as recall and y as precision. Computes step-function area under the curve per series.

Parameters:

Name Type Description Default
position ('end', 'corner')

Where to place the label. "end" puts it at the rightmost point of each series curve; "corner" anchors it near the top-right of the plot area.

"end"
format str

Python format spec applied to the AP value.

".3f"
prefix str

Text prepended to the formatted metric value.

"AP = "

Examples:

>>> import ferrum as fm
>>> chart = fm.pr_chart(model, X_test, y_test)
>>> annotated = chart + fm.APLabel()

BrierLabel dataclass

Auto-placed Brier-score annotation for calibration charts.

x is treated as predicted probability and y as observed rate per bin. Multi-series charts emit one Brier score per series. Lower scores indicate better calibration.

Parameters:

Name Type Description Default
position ('end', 'corner')

Where to place the label. "corner" anchors it near the top-right of the plot area; "end" puts it at the last bin.

"end"
format str

Python format spec applied to the Brier score value.

".3f"
prefix str

Text prepended to the formatted metric value.

"Brier = "

Examples:

>>> import ferrum as fm
>>> chart = fm.calibration_chart(model, X_test, y_test)
>>> annotated = chart + fm.BrierLabel()

OutlierLabel dataclass

Auto-label high-leverage or high-residual points on a scatter chart.

chart + OutlierLabel() scans the chart's y column for values whose z-score exceeds threshold, then overlays text labels at those points. The label text is taken from label_field when supplied, otherwise from the field column, otherwise from the y value.

Parameters:

Name Type Description Default
threshold float

Z-score threshold above which a point is considered an outlier and labelled.

3.0
field str

Column to compute z-scores from. Defaults to the chart's y encoding field.

None
label_field str

Column whose value is used as the text label. Defaults to field when omitted.

None
max_labels int

Maximum number of labels to emit. Points are ranked by absolute z-score and only the top max_labels are labelled.

10

Examples:

>>> import ferrum as fm
>>> chart = fm.residuals_chart(model, X_test, y_test)
>>> annotated = chart + fm.OutlierLabel(threshold=2.5, max_labels=5)

Title dataclass

Chart title with optional subtitle.

Accepted everywhere a title string is accepted: Chart(title=...), Chart.properties(title=...), HConcat/VConcat/Layer(title=...). Passing a bare string is equivalent to Title(text=string).

Parameters:

Name Type Description Default
text str

Primary title text.

required
subtitle str

Secondary line below the title; None suppresses the second line.

None
anchor ('start', 'middle', 'end')

Horizontal anchor.

"start"
offset float

Pixel offset from plot area; defaults to the theme's title_offset.

None
font_size float

Title font size in points.

None
font_weight str

Title font weight (e.g. "600", "bold").

None
color str

Title color as a CSS color string.

None
subtitle_font_size float

Subtitle font size; defaults to font_size * 0.85.

None
subtitle_color str

Subtitle color; defaults to the theme's label_color.

None

Examples:

>>> import ferrum as fm
>>> title = fm.Title("My Chart", subtitle="subtitle text", anchor="start")
>>> fm.Chart(df).mark_point().encode(x="x", y="y").properties(title=title)

to_spec_dict

to_spec_dict() -> dict

Serialize to the dict shape the Rust binding expects.

Only emits non-default fields so the JSON sent to Rust stays minimal and forward-compatible.

Selection dataclass

Immutable selection descriptor.

Created by selection_point(), selection_interval(), selection_single(), or selection_multi() — do not construct directly.

Attributes:

Name Type Description
name str

Stable identifier used to link this selection to conditional encodings and to the WASM renderer.

kind {'point', 'interval'}

Selection type.

params dict

Resolved parameters forwarded to the Rust SelectionSpec.

Examples:

Build a conditional encoding from a selection:

>>> import ferrum as fm
>>> sel = fm.selection_point()
>>> color_enc = sel.when(fm.Color("category")).otherwise(fm.value("#cccccc"))
>>> fm.Chart(df).mark_point().encode(
...     x=fm.X("x"), y=fm.Y("y"), color=color_enc
... ).add_selection(sel)

when

when(if_encoding: Any) -> _SelectionCondition

Start a conditional encoding: sel.when(Color("x")).otherwise(value("#ccc")).

to_spec_dict

to_spec_dict() -> dict

Serialize to a dict matching the Rust SelectionSpec shape.

SelectionMark dataclass

Visual style for the interval selection brush rectangle.

Pass an instance to selection_interval(mark=...) to override the default brush appearance.

Parameters:

Name Type Description Default
fill str

Hex colour string for the brush fill (e.g. "#4287f5"). Defaults to the renderer's built-in blue.

None
stroke str

Hex colour string for the brush border. Defaults to the renderer's built-in grey.

None
fill_opacity float

Opacity of the fill (0.0 = transparent, 1.0 = opaque).

0.3
stroke_opacity float

Opacity of the border.

1.0
stroke_width float

Border line width in pixels.

1.0
stroke_dash list of float

Dash pattern for the border (e.g. [4, 2]). Solid when omitted.

None

Examples:

>>> import ferrum as fm
>>> brush_style = fm.SelectionMark(fill="#ff9900", fill_opacity=0.2, stroke_dash=[4, 2])
>>> brush = fm.selection_interval(mark=brush_style)

to_spec_dict

to_spec_dict() -> dict

Serialize to a dict matching the Rust SelectionMarkStyle shape.

ConditionalSpec dataclass

Resolved conditional encoding — produced by sel.when(...).otherwise(...).

Do not construct directly. Build one through the selection fluent API::

sel.when(<if_encoding>).otherwise(<else_encoding>)

Attributes:

Name Type Description
selection_name str

Name of the Selection that drives the condition.

if_selected encoding channel or value(...)

Encoding applied when a datum falls inside the selection.

if_not encoding channel or value(...)

Encoding applied when a datum falls outside the selection.

Examples:

>>> import ferrum as fm
>>> sel = fm.selection_point()
>>> cond = sel.when(fm.Color("category")).otherwise(fm.value("#cccccc"))
>>> type(cond).__name__
'ConditionalSpec'

to_spec_dict

to_spec_dict() -> dict

Serialize to a dict matching the Rust ConditionalEncoding shape.

ComparedModelSource

Multi-model wrapper exposing the same surface as ModelSource.

Every derived-data method is proxied through each underlying ModelSource and the per-model outputs are concatenated with a model: Utf8 column stamped on each frame, so downstream chart builders can route color="model" to render one curve per model.

_X, _y, _feature_names, and _class_names resolve to the first source's values (every wrapped source shares X / y by construction in ModelSource.compare, so any one will do); accessing _model raises since there is no single estimator. model_names reports the configured ordering.

Parameters:

Name Type Description Default
sources dict[str, ModelSource]

Mapping from model name (used for the model column) to the underlying ModelSource. Must contain at least one entry — passing an empty dict raises ValueError.

required

Examples:

>>> import ferrum as fm
>>> cms = fm.ModelSource.compare({"ridge": ridge, "lasso": lasso}, X, y)
>>> fm.roc_chart(cms)                  # overlay both curves
>>> cms.model_names
['ridge', 'lasso']
>>> cms.roc_curve()                    # long-form frame with `model` column

model_names property

model_names: list[str]

Ordered list of model display names.

Returns the keys of the sources dict supplied at construction time, in insertion order. Each name corresponds to the value written into the model column on every derived-data DataFrame.

Returns:

Type Description
list[str]

Model names in the order they were registered.

ModelSource

Bases: PredictionsMixin, ClassificationCurvesMixin, FeatureImportanceMixin, ModelSelectionMixin, ClusteringMixin, RankingMixin, BaseSource

Wrap a fitted estimator + dataset and expose model-diagnostic derived data as polars DataFrames.

Constructing a ModelSource is sklearn-free — only attribute introspection runs at __init__ time. Derived-data methods that need sklearn / shap / umap lazy-import on call, so import ferrum never pulls those packages into the user's process unless they actually compute a diagnostic that requires them.

Each derived-data method returns a long-form polars DataFrame whose schema is documented in ferrum._diagnostics.schemas — chart builders and Visualizers consume the same frames.

Parameters:

Name Type Description Default
model Any

A fitted estimator. Must expose at least predict; some methods require additional protocol attributes (predict_proba, coef_, feature_importances_, cluster_centers_, explained_variance_ratio_, …) and raise AttributeError with the missing attribute name when called against an incompatible model.

required
X DataFrame | DataFrame | Table | ndarray

Feature matrix. Coerced internally to a polars DataFrame; any narwhals-compatible input also works.

required
y array - like

Target. Required by methods that depend on ground truth (every method except probabilities and the unsupervised silhouette / pca_variance / embeddings / intercluster_distance / rank1d(algorithm != "covariance") / rank2d family).

None
feature_names sequence of str

Column labels. Defaults to X.columns when X is a DataFrame, or ["f0", "f1", ...] otherwise.

None
class_names sequence of str

Per-class display labels for classification diagnostics. Defaults to model.classes_ when available, else the unique values of y.

None
sample_weight array - like

Per-row weights forwarded to sklearn scorers that accept them.

None
random_state int

Seed propagated to every derived-data method whose underlying compute consumes randomness (importances permutation, SHAP background sampling, UMAP / t-SNE / MDS embeddings, cross-validation curves, partial-dependence sampling). Deterministic methods ignore the value.

None

Examples:

>>> import ferrum as fm
>>> source = fm.ModelSource(model, X, y, random_state=0)
>>> fm.roc_chart(source)              # use directly with a figure function
>>> source.predictions()              # access derived data as a DataFrame
>>> source.confusion_matrix(normalize="true")

X property

X: DataFrame

Feature matrix coerced to a polars DataFrame.

Returns the value supplied to __init__ (after coercion). Use this for read-only access from chart builders and external callers — source._X is an internal alias preserved for back-compat.

y property

y: 'pl.Series | None'

Target series, or None when no y was supplied.

Returns the polars Series the constructor coerced from the y argument. None means unsupervised — methods that need ground truth raise on call.

model property

model: Any

The wrapped fitted estimator.

Returns the model object supplied at construction time unchanged. Chart builders use it for occasional native introspection (e.g. model.classes_, model.n_clusters); prefer the public derived-data methods when one exists.

feature_names property

feature_names: list[str]

Column labels for the feature matrix.

Returns the names supplied at construction time, or the DataFrame column names when X was a DataFrame, or ["f0", "f1", ...] for unlabeled array inputs.

Returns:

Type Description
list[str]

Feature names in the same order as the columns of X.

capabilities property

capabilities: frozenset[str]

Protocol attributes present on the wrapped estimator.

A frozen subset of _PROTOCOL_ATTRS ("predict", "predict_proba", "coef_", "feature_importances_", …) detected at construction time via hasattr. Derived-data methods gate on this set to pick the appropriate code path and raise AttributeError with a clear message when a required attribute is absent.

Returns:

Type Description
frozenset[str]

Attribute names that are present on the wrapped model.

rank1d

rank1d(*, algorithm: str = 'shapiro') -> pl.DataFrame

Univariate feature ranking.

algorithm in {"shapiro", "variance", "covariance"}. The Shapiro-Wilk and variance algorithms operate on X alone; "covariance" ranks features by absolute sample covariance with y and therefore requires y to be present.

Output schema (SCHEMA_RANK1D): feature: Utf8, score: Float64, rank: Int64. Rows are pre-sorted by descending score so rank=1 is always the top feature.

rank2d

rank2d(*, algorithm: str = 'pearson') -> pl.DataFrame

Pairwise feature ranking — long-form correlation matrix.

algorithm in {"pearson", "spearman", "kendall", "covariance"}. All algorithms now run in Rust (Kendall uses Knight's O(n log n)).

Output schema (SCHEMA_RANK2D): feature_x: Utf8, feature_y: Utf8, correlation: Float64 — one row per ordered pair of features, p × p rows total.

silhouette

silhouette(*, k: int | None = None) -> pl.DataFrame

Per-sample silhouette values, sorted within cluster descending.

Returns one row per sample with columns sample_id (original X index), y_position (sequential 0..n-1 stack order — used by mark_silhouette to render bars in a tightly-packed Rousseeuw layout), cluster, and silhouette_value.

k is informational; if provided, the result is filtered to clusters in range(k).

pca_variance

pca_variance(*, n_components: int | None = None) -> pl.DataFrame

Explained-variance ratio per principal component plus the cumulative running sum.

If the wrapped model exposes explained_variance_ratio_ (e.g. sklearn.decomposition.PCA), reads it directly (backward compat). Otherwise computes from raw X via Rust SVD.

embeddings

embeddings(*, method: str = 'umap', n_components: int = 2, **method_kwargs: Any) -> pl.DataFrame

Low-dimensional embedding of X via UMAP / t-SNE / PCA.

Returns dim_0dim_{n_components-1} plus a label column (y when provided, else zeros — used to color the scatter). random_state is taken from the source's random_state.

intercluster_distance

intercluster_distance(k: int, *, method: str = 'mds') -> pl.DataFrame

2D embedding of cluster centers + cluster size.

Returns one row per cluster with cluster (Int64), x / y (Float64, the 2D embedded coordinate), and size (Int64, sample count). Requires the wrapped model to expose cluster_centers_.

learning_curve

learning_curve(*, cv: int = 5, scoring: Any = None, train_sizes: Any = None) -> pl.DataFrame

Learning curve: score per (train_size, fold, split).

Returns long-form rows — one per (train_size, fold, split). Each row carries the per-fold score plus the per-(train_size, split) aggregates mean_score, std_score, lower, upper (95% CI on the mean). Chart builders dedupe by (train_size, split) to render a ribbon + line; the per-fold rows enable per-fold strip overlays if a future caller wants them.

validation_curve

validation_curve(param: str, values: Any, *, cv: int = 5, scoring: Any = None) -> pl.DataFrame

Validation curve: score per (param_value, fold, split).

Same shape as learning_curve but parameterized by an estimator hyperparameter sweep. param is the kwarg name on the wrapped estimator (e.g. "alpha" for Ridge).

cv_scores

cv_scores(*, cv: int = 5, scoring: Any = None) -> pl.DataFrame

Per-fold cross-validation scores.

Returns one row per (fold, split) — train and test scores for each cross-validation fold. Chart builders use this for boxplot / bar / strip distributions across folds.

alpha_selection

alpha_selection(alphas: Any, *, cv: int = 5, scoring: Any = None) -> pl.DataFrame

Regularization-strength sweep for linear models.

Returns one row per (alpha, fold) — the per-fold test score on the held-out split — plus per-alpha mean_score / std_score aggregates. Chart builders dedupe by alpha to render a single line, and use argmax(mean_score) to mark the best alpha.

importances

importances(*, method: str = 'builtin', n_repeats: int = 30, scoring: Any = None, random_state: int | None = None) -> pl.DataFrame

Feature importance per feature, sorted by descending |importance|.

method="builtin" reads the wrapped model's feature_importances_ (tree-based estimators) or coef_ (linear estimators, averaged absolute value across classes for multi-output linears). std is zero in this path — sklearn's built-in attribute exposes no per-feature variance.

method="permutation" calls sklearn's permutation_importance with n_repeats/scoring and populates std with the per-feature standard deviation across repeats.

shap_values

shap_values(*, background: Any = None, max_evals: int = 500) -> pl.DataFrame

Long-form SHAP values per (sample, feature, class).

Returns a DataFrame with sample_id, feature, shap_value, feature_value, feature_value_normalized, class_label.

  • Regression: class_label is the constant "target" on every row.
  • Binary classifiers: class_label is the positive-class name on every row; SHAP values are for the positive class.
  • Multi-class classifiers: one row per (sample, feature, class); class_label carries the class name. The result has n_samples * n_features * n_classes rows total.

Explainer is auto-picked by model capability:

  • coef_: shap.LinearExplainer (deterministic, fast).
  • feature_importances_: shap.TreeExplainer (deterministic for tree ensembles).
  • otherwise: shap.KernelExplainer (model-agnostic; uses the first min(50, N) rows of X as the background unless an explicit background array is passed).

partial_dependence

partial_dependence(features: list[str | int], *, grid_resolution: int = 100, kind: str = 'average') -> pl.DataFrame

Partial dependence per feature.

kind="average" (default) returns the marginal PD curve per feature with sample_id = -1 (one row per grid point per feature).

kind="individual" returns per-sample ICE curves: one row per (feature, sample_id, grid_point) triple with sample_id in [0, n_samples). Chart builders pair this with the detail encoding channel on sample_id to render one polyline per sample.

kind="both" returns the union of the two: ICE rows plus average rows (sample_id = -1), so a downstream chart can overlay both layers on the same DataFrame.

roc_curve

roc_curve(*, average: str | None = None, drop_intermediate: bool = True) -> pl.DataFrame

ROC curve(s). One row per (class, threshold). auc repeats per class.

For binary classifiers with average=None (default), returns a single curve on the positive (second) class. For multiclass, returns one-vs-rest curves per class; pass average in {"micro", "macro", "weighted"} to additionally include a summary curve under class="<average>".

pr_curve

pr_curve(*, average: str | None = None) -> pl.DataFrame

Precision-recall curve(s). One row per (class, threshold).

For binary classifiers, returns a single curve on the positive (second) class — average is accepted for API symmetry with the multiclass path but has no effect because binary classifiers have only one curve to draw. For multiclass:

  • average=None (default) — returns one-vs-rest curves per class.
  • average in {"micro", "macro", "weighted"} — returns a single summary curve with class="<average>" and no per-class rows. Macro / weighted variants interpolate per- class precision over a shared recall grid (100 points); micro ravels the binarized labels into one curve. threshold is NaN on every row of macro / weighted summaries (recall-grid interpolation discards thresholds) and follows sklearn's padding convention for micro.

threshold is NaN at the final (recall=0) point of every per-class curve per sklearn's convention.

calibration_curve

calibration_curve(*, n_bins: int = 10, strategy: str = 'uniform') -> pl.DataFrame

Calibration (reliability) curve for binary classifiers.

Returns one row per non-empty bin with mean_predicted, fraction_positive, and count. Uses sklearn's calibration_curve for the means/fractions and a parallel pass over y_score to count rows per bin.

cumulative_gain

cumulative_gain() -> pl.DataFrame

Cumulative-gain curve per class. Appends a 2-row class='baseline' diagonal for plotting reference.

lift_curve

lift_curve() -> pl.DataFrame

Lift curve per class. Appends a 2-row class='baseline' line at lift=1.0.

discrimination_threshold

discrimination_threshold(*, n_thresholds: int = 50, cv: Any = None) -> pl.DataFrame

Discrimination threshold sweep — binary classifiers only.

Sweeps n_thresholds evenly-spaced thresholds in [0, 1] and reports precision, recall, F1, and queue_rate at each. queue_rate is the hand-computed fraction (y_score >= t).mean().

When cv is an int, runs the same sweep on each fold's held-out scores from a freshly-cloned + re-fit estimator and averages per-threshold metrics across folds. Pass a splitter object with a .split() method to override.

confusion_matrix

confusion_matrix(*, normalize: str | None = None) -> pl.DataFrame

Confusion matrix in long form: one row per (actual, predicted) cell.

normalize: None for raw counts, "true"/"pred"/"all" for sklearn-style normalization. value is the (possibly normalized) count; value_fmt is a stringified label suitable for mark_text overlay (integer counts when unnormalized, two-decimal fractions when normalized).

predictions

predictions() -> pl.DataFrame

Return y_true, y_pred, residual, studentized_residual, cooks_distance, leverage.

leverage is the diagonal of the hat matrix H = X (XᵀX)⁻¹ Xᵀ for linear estimators (those exposing coef_); NaN otherwise. Used by the residuals-vs-leverage panel of multi-panel residuals charts.

probabilities

probabilities() -> pl.DataFrame

Return y_true + one column per class with predicted probability.

compare classmethod

compare(models: dict[str, Any], X: Any, y: Any = None, **kwargs: Any) -> 'ComparedModelSource'

Build a ComparedModelSource over one ModelSource per model.

Each value in models is wrapped in its own ModelSource with the shared X and y. The returned ComparedModelSource proxies every derived-data method through all wrapped sources and stamps the model name as a model column on the concatenated output, so downstream chart builders can route color="model".

Parameters:

Name Type Description Default
models dict[str, Any]

Mapping from display name to fitted estimator. Each estimator is wrapped in its own ModelSource constructed with the shared X, y, and any additional kwargs (e.g. random_state, feature_names, class_names).

required
X array - like

Feature matrix shared by all models. Accepted types match ModelSource.__init__.

required
y array - like

Target shared by all models. Required by most derived-data methods (same constraints as ModelSource).

None
**kwargs Any

Keyword arguments forwarded verbatim to each ModelSource constructor (e.g. random_state, feature_names, class_names, sample_weight).

{}

Returns:

Type Description
ComparedModelSource

Multi-model wrapper whose derived-data methods return long-form DataFrames with an extra model: Utf8 column.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import Ridge, Lasso
>>> cms = fm.ModelSource.compare(
...     {"ridge": Ridge().fit(X, y), "lasso": Lasso().fit(X, y)},
...     X, y, random_state=0,
... )
>>> fm.roc_chart(cms)          # overlay both ROC curves
>>> cms.model_names
['ridge', 'lasso']

CalibrationVisualizer

Bases: FerrumVisualizer

Calibration (reliability) diagram for a probability classifier.

Wraps ModelSource.calibration_curve(). Records the mean squared deviation between mean_predicted and fraction_positive as calibration_error.

Parameters:

Name Type Description Default
*models Any

One or more fitted classifiers. Pass a single model for a single-curve diagram; pass two or more (or a single dict positional argument like {"a": m_a, "b": m_b}) to overlay multiple curves via ComparedModelSource.

()
n_bins int

Number of bins for the calibration histogram.

10
strategy ('uniform', 'quantile')

Bin-edge strategy (matches sklearn.calibration).

"uniform"
random_state int
None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.CalibrationVisualizer(clf, n_bins=5).fit(X, y)
>>> viz_overlay = fm.CalibrationVisualizer(clf_a, clf_b).fit(X, y)

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ClassBalanceVisualizer

Bases: FerrumVisualizer

Bar chart of per-class label counts, computed from target labels alone.

Accepts both the standard sklearn fit(X, y) signature and the label-only shorthand fit(y) — when the second argument is omitted, the first positional argument is treated as the label array. No model is required; pass nothing for the model argument (it is always None internally).

After fit, _metrics contains:

  • n_classes — number of unique class labels.
  • imbalance_ratiomax_count / max(min_count, 1), where 1.0 indicates perfectly balanced classes and larger values indicate increasing imbalance.

Parameters:

Name Type Description Default
random_state int

Accepted for API symmetry with model-backed visualizers but intentionally never consumed — ClassBalanceVisualizer overrides fit() and never constructs a ModelSource. Documented as a permanent no-op so callers that script over visualizers don't have to special-case which ones accept the kwarg.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.ClassBalanceVisualizer().fit(X, y)
>>> viz.show()                   # returns the per-class count bar Chart
>>> viz._metrics["imbalance_ratio"]

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ClassificationReportVisualizer

Bases: FerrumVisualizer

Per-class precision, recall, and F1-score heatmap with text overlay.

Wraps _classification_report_chart(). Produces a rect-mark heatmap with one row per class and columns for precision, recall, and F1. Records f1_macro (macro-averaged F1 across all classes, computed via sklearn.metrics.f1_score) as the headline scalar metric.

Parameters:

Name Type Description Default
model Any

Fitted classifier implementing predict.

required
random_state int

Seed forwarded to ModelSource for reproducible train/test splits.

None
theme Theme

Ferrum theme applied to the output chart.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.ClassificationReportVisualizer(clf).fit(X, y)
>>> viz._metrics["f1_macro"]
0.91
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ClassPredictionErrorVisualizer

Bases: FerrumVisualizer

Stacked-bar chart of actual-class composition per predicted class.

For each predicted class label on the x-axis, the bar is stacked by the true class, showing how often a predicted class is correct vs. confused with another class. When normalize=True every bar is scaled to 100 % so proportions are comparable across imbalanced classes.

After fit, overall accuracy (total correct / total predictions, computed from raw counts regardless of normalize) is stored in _metrics["accuracy"].

Parameters:

Name Type Description Default
model Any

Fitted sklearn classifier that exposes predict.

required
normalize bool

When True, each predicted-class bar is scaled to sum to 1 (100 % stacked view). When False, bars show absolute counts.

False
random_state int

Seed forwarded to ModelSource for any randomness in data prep.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.ClassPredictionErrorVisualizer(model).fit(X, y)
>>> viz.show()                   # returns the stacked-bar Chart
>>> viz._metrics["accuracy"]     # proportion of correct predictions

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ConfusionMatrixVisualizer

Bases: FerrumVisualizer

Confusion-matrix heatmap with per-cell counts or normalized fractions.

Wraps ModelSource.confusion_matrix(). Renders a rect-mark heatmap with cell-value text overlaid. Records accuracy (diagonal sum / total, always computed from raw counts regardless of the normalize setting).

Parameters:

Name Type Description Default
model Any

Fitted classifier implementing predict.

required
normalize ('true', 'pred', 'all')

Row-normalization strategy passed to the chart builder. "true" normalizes each row by the true-class total (recall fractions); "pred" by the predicted-class total (precision fractions); "all" by the grand total; None shows raw counts.

"true"
random_state int

Seed forwarded to ModelSource for reproducible train/test splits.

None
theme Theme

Ferrum theme applied to the output chart.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.ConfusionMatrixVisualizer(clf).fit(X, y)
>>> viz._metrics["accuracy"]
0.94
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

CooksDistanceVisualizer

Bases: FerrumVisualizer

Cook's distance diagnostic for a regression estimator.

Surfaces max_studentized (the largest absolute studentized residual) as a quick proxy for influential observations; the leverage-aware Cook's D itself is materialized by ModelSource.predictions().cooks_distance for linear estimators and is rendered by mark_residuals(cook_threshold=...). This visualizer plots the residuals chart with the leverage panel enabled.

Parameters:

Name Type Description Default
model Any

Fitted regression estimator (must expose coef_ for the leverage-aware Cook's distance).

required
threshold float or 'auto'

Cook's-distance threshold for highlighting outliers on the residuals-vs-leverage panel. Forwarded to _residuals_chart_from_source(cook_threshold=...), which injects _cook_outlier_x / _cook_outlier_y columns (keyed on leverage and the studentized residual) and the leverage panel renders them as a red-filled overlay layer. "auto" uses the conventional 4 / n rule (Hair et al.).

None
random_state int
None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.CooksDistanceVisualizer(linear_model).fit(X, y)
>>> viz._metrics["max_studentized"]
3.42

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

DiscriminationThresholdVisualizer

Bases: FerrumVisualizer

Sweep a decision threshold for a binary classifier and plot four metric curves.

Evaluates precision, recall, f1, and queue_rate (or a caller-supplied subset) at n_thresholds evenly-spaced probability thresholds between 0 and 1. After fit, the F1-maximising threshold and its F1 score are available via _metrics.

Parameters:

Name Type Description Default
model Any

Fitted binary sklearn estimator that exposes predict_proba.

required
n_thresholds int

Number of probability thresholds to evaluate across [0, 1].

50
metrics tuple of str

Which per-threshold metrics to include as curves in the chart. Passed through to the underlying ModelSource.discrimination_threshold call and to mark_discrimination_threshold.

("precision", "recall", "f1", "queue_rate")
cv Any

Cross-validation strategy forwarded to ModelSource.discrimination_threshold. None uses the model as-is (no CV averaging).

None
threshold_line bool

When True, overlays a vertical rule at the F1-maximising threshold (matches the figure-level discrimination_threshold_chart(threshold_line=True)).

False
random_state int

Seed forwarded to ModelSource for any randomness in CV splits.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.DiscriminationThresholdVisualizer(model).fit(X, y)
>>> viz.show()                   # returns the four-curve Chart
>>> viz._metrics["best_threshold"], viz._metrics["best_f1"]

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

FeatureImportancesVisualizer

Bases: FerrumVisualizer

Visualize feature importances from a fitted sklearn estimator.

Wraps importance_chart in the sklearn-protocol visualizer interface. method="builtin" reads feature_importances_ or coef_ directly from the estimator (std is 0 in this case). method="permutation" runs sklearn.inspection.permutation_importance using the supplied random_state seed. The headline metric recorded in _metrics is top_feature_importance — the importance of the highest-ranked feature after sorting.

Parameters:

Name Type Description Default
model Any

Fitted sklearn-compatible estimator. Must expose feature_importances_ or coef_ (method="builtin") or support predict / predict_proba (method="permutation").

required
method ('builtin', 'permutation')

Strategy for extracting importances. "builtin" reads the estimator attribute directly (zero standard deviation). "permutation" shuffles each feature and measures the drop in score.

"builtin"
top_k int or None

Maximum number of features to display, ranked by importance. Pass None to show all features.

20
orient ('horizontal', 'vertical')

Bar orientation in the rendered chart.

"horizontal"
error_bars bool

Whether to draw ±1 std error bars. Has no visual effect when method="builtin" because std is always 0 in that case.

True
random_state int or None

RNG seed forwarded to permutation_importance. Ignored when method="builtin".

None
theme Theme or None

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import RandomForestClassifier
>>> model = RandomForestClassifier(n_estimators=50, random_state=0).fit(X_train, y_train)
>>> viz = fm.FeatureImportancesVisualizer(model).fit(X_train, y_train)
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

FerrumVisualizer

Base class for sklearn-protocol model-diagnostic visualizers.

Concrete visualizers either override _materialize + _build_chart (the standard model-backed flow) or override fit directly (no-model / multi-fit / label-only flow).

Parameters:

Name Type Description Default
model Any

Fitted estimator that will be wrapped in a ModelSource at fit time. Pass None for no-model visualizers (rank / parallel coordinates / class balance).

None
random_state int

Seed forwarded to the underlying ModelSource. Ignored when the wrapped derived-data compute is deterministic.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> viz = fm.ROCVisualizer(model, random_state=0).fit(X, y)
>>> viz.show()                # returns a Chart
>>> viz._metrics              # headline metric(s)

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

PRVisualizer

Bases: FerrumVisualizer

Precision-recall curve(s) for binary or multiclass classifiers.

Wraps ModelSource.pr_curve(). Records ap_mean (average precision averaged across classes) as the headline metric.

Parameters:

Name Type Description Default
model Any

Fitted classifier exposing predict_proba or decision_function.

required
random_state int
None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.PRVisualizer(clf).fit(X, y)
>>> viz._metrics["ap_mean"]
0.88

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

PredictionErrorVisualizer

Bases: FerrumVisualizer

Actual-vs-predicted scatter for a regression estimator.

Wraps ModelSource.predictions(). Records rmse as the headline metric; the chart shows y_true on x and y_pred on y with an optional identity line and CI / reference band overlays.

Parameters:

Name Type Description Default
model Any

Fitted regression estimator.

required
reference_line bool

Overlay the dashed y = x diagonal.

True
ci float

Confidence level in (0, 1). When set, overlays a ribbon spanning the central ci fraction of residuals around the reference line. Raises ValueError if not in (0, 1).

None
reference_band bool

When True (and ci is None), overlays a ±1 RMSE ribbon around the reference line.

False
random_state int
None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.PredictionErrorVisualizer(model, ci=0.95).fit(X, y)
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ResidualsVisualizer

Bases: FerrumVisualizer

Residuals-vs-fitted diagnostic for a regression estimator.

Wraps ModelSource.predictions(). Records rmse and mae as headline metrics; the chart shows y_pred on x and the chosen residual variant on y with a horizontal reference line at zero.

Parameters:

Name Type Description Default
model Any

Fitted regression estimator (must implement predict).

required
kind ('studentized', 'raw', 'scaled')

Which residual variant to plot. "studentized" uses the leverage-aware hat-matrix form when model exposes coef_; otherwise falls back to internally-studentized (residual / std).

"studentized"
random_state int

Forwarded to the underlying ModelSource.

None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.ResidualsVisualizer(model).fit(X, y)
>>> viz._metrics["rmse"]
1.234
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ROCVisualizer

Bases: FerrumVisualizer

ROC curve(s) for binary or multiclass classifiers.

Wraps ModelSource.roc_curve(). per_class=True (default) draws one curve per class; pass per_class=False to plot a single averaged curve. Records auc_mean as the headline metric.

Parameters:

Name Type Description Default
model Any

Fitted classifier (must implement predict_proba or decision_function).

required
micro bool

Compute the micro-averaged AUC.

True
macro bool

Compute the macro-averaged AUC. Takes precedence over micro when choosing which averaged curve to plot at per_class=False.

True
per_class bool

Render one curve per class. When False, only the averaged curve is rendered.

True
random_state int
None
theme Theme
None

Examples:

>>> import ferrum as fm
>>> viz = fm.ROCVisualizer(clf).fit(X, y)
>>> viz._metrics["auc_mean"]
0.92

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

SHAPVisualizer

Bases: FerrumVisualizer

Visualize SHAP values from a fitted sklearn estimator.

Wraps the shap_chart family in the sklearn-protocol visualizer interface. Requires the shap library (pip install ferrum[shap]). Three chart kinds are supported: "beeswarm" shows per-sample SHAP scatter colored by feature value; "bar" shows mean absolute SHAP aggregated per feature; "waterfall" shows the cumulative contribution for a single sample selected by sample_idx. The headline metric recorded in _metrics is top_abs_shap — the maximum mean absolute SHAP value across all features.

Parameters:

Name Type Description Default
model Any

Fitted sklearn-compatible estimator supported by the shap library (e.g. tree ensembles, linear models with a shap.Explainer).

required
kind ('beeswarm', 'bar', 'waterfall')

Chart style to render. "waterfall" requires sample_idx to be set; a ValueError is raised at .show() time if it is omitted.

"beeswarm"
max_display int

Maximum number of features to include in the chart, ranked by mean absolute SHAP value.

20
sample_idx int or None

Row index of the sample to explain. Required when kind="waterfall"; ignored for "beeswarm" and "bar".

None
order ('abs_mean', 'max')

Feature ordering strategy applied to all three kind values. "abs_mean" ranks features by mean(|shap_value|) across the dataset; "max" ranks by max(|shap_value|) to surface features with high-impact outliers. For kind="bar" the same aggregation drives both the bar's x-value and the sort order; for kind="waterfall" it selects which features are shown for the single sample and the order they appear in.

"abs_mean"
background Any or None

Background dataset passed to the SHAP explainer for models that require a reference distribution (e.g. kernel SHAP). Pass None to use the explainer's default.

None
random_state int or None

RNG seed forwarded to the underlying ModelSource. Ignored when SHAP computation is deterministic.

None
theme Theme or None

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> model = GradientBoostingClassifier(random_state=0).fit(X_train, y_train)
>>> viz = fm.SHAPVisualizer(model, kind="beeswarm").fit(X_train, y_train)
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

SHAPBeeswarmVisualizer

Bases: _SHAPBaseMixin, FerrumVisualizer

Per-sample SHAP scatter colored by z-scored feature value.

Parameters:

Name Type Description Default
model Any

Fitted sklearn-compatible estimator supported by the shap library (e.g. tree ensembles, linear models).

required
max_display int

Maximum number of features ranked by order.

20
order ('abs_mean', 'max')

Feature ranking criterion. "abs_mean" ranks by mean absolute SHAP; "max" by max absolute SHAP.

"abs_mean"
background Any

Background dataset passed to the SHAP explainer for kernel- SHAP models. Tree SHAP ignores this.

None
random_state forwarded to ``FerrumVisualizer``.
None
theme forwarded to ``FerrumVisualizer``.
None

Examples:

>>> import ferrum as fm
>>> viz = fm.SHAPBeeswarmVisualizer(model, max_display=15).fit(X, y)
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

SHAPBarVisualizer

Bases: _SHAPBaseMixin, FerrumVisualizer

Mean-absolute SHAP per feature as a horizontal bar chart.

Parameters mirror :class:SHAPBeeswarmVisualizer; see that class for the full parameter list.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> viz = fm.SHAPBarVisualizer(GradientBoostingClassifier().fit(X_train, y_train))
>>> chart = viz.chart(X_test, y_test)

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

SHAPWaterfallVisualizer

Bases: _SHAPBaseMixin, FerrumVisualizer

Cumulative per-feature SHAP contributions for one sample.

Parameters:

Name Type Description Default
model Any

Fitted sklearn-compatible estimator supported by the shap library.

required
sample_idx int

Row index (0-based) of the sample to explain. Required.

required
max_display int

Maximum number of features to include in the waterfall, ranked by order.

20
order ('abs_mean', 'max')

Feature ranking criterion (drives both the top-max_display selection and the bar order).

"abs_mean"
background Any

Background dataset passed to the SHAP explainer.

None
random_state forwarded to ``FerrumVisualizer``.
None
theme forwarded to ``FerrumVisualizer``.
None

Raises:

Type Description
ValueError

If sample_idx is missing at __init__ time.

Examples:

>>> import ferrum as fm
>>> viz = fm.SHAPWaterfallVisualizer(model, sample_idx=3).fit(X, y)
>>> viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

LearningCurveVisualizer

Bases: FerrumVisualizer

Visualize training and cross-validation scores as training size grows.

Wraps learning_curve_chart in the sklearn visualizer protocol. Call fit(X, y) to run cross-validation across the requested training-size grid; call show() to retrieve the rendered Chart. The headline metric final_test_score (mean test score at the largest training size) is recorded in _metrics and shown in repr.

Parameters:

Name Type Description Default
model Any

Unfitted or fitted sklearn-compatible estimator.

required
cv int

Number of cross-validation folds passed to sklearn.model_selection.learning_curve.

5
scoring str or callable

Sklearn scoring string or callable. Defaults to the estimator's own score method when None.

None
train_sizes array - like

Relative or absolute training-set sizes to evaluate. Passed directly to learning_curve; defaults to np.linspace(0.1, 1.0, 5) when None.

None
ci_style ('band', 'bar')

How to render the cross-validation confidence interval. "band" draws a shaded ribbon; "bar" draws error bars.

"band"
random_state int

Seed forwarded to ModelSource and from there to learning_curve for reproducible CV splits (ChaCha8 RNG).

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> viz = fm.LearningCurveVisualizer(
...     LogisticRegression(), cv=5, scoring="accuracy"
... ).fit(X_train, y_train)
>>> chart = viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ValidationCurveVisualizer

Bases: FerrumVisualizer

Visualize train/test scores as a single hyperparameter is swept.

Wraps validation_curve_chart in the sklearn visualizer protocol. For each value in values, sklearn.model_selection.validation_curve runs cv folds and records the mean score. The value that maximises the mean test score is stored as best_param in _metrics; the corresponding mean score is stored as best_test_score.

Parameters:

Name Type Description Default
model Any

Unfitted or fitted sklearn-compatible estimator.

required
param str

Name of the hyperparameter to sweep, e.g. "C" for LogisticRegression or "max_depth" for tree estimators. Must be a valid __init__ parameter of model.

required
values array - like

Grid of candidate values for param. Passed directly to sklearn.model_selection.validation_curve as param_range.

required
cv int

Number of cross-validation folds.

5
scoring str or callable

Sklearn scoring string or callable. Defaults to the estimator's own score method when None.

None
log_scale bool or 'auto'

Whether to render the x-axis (param values) on a log scale. "auto" enables log scale when the ratio between the largest and smallest value exceeds 100.

"auto"
ci_style ('band', 'bar')

How to render the cross-validation confidence interval. "band" draws a shaded ribbon; "bar" draws error bars.

"band"
random_state int

Seed forwarded to ModelSource for reproducible CV splits (ChaCha8 RNG).

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.svm import SVC
>>> import numpy as np
>>> viz = fm.ValidationCurveVisualizer(
...     SVC(), param="C", values=np.logspace(-3, 3, 7), cv=5
... ).fit(X_train, y_train)
>>> chart = viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

CVScoresVisualizer

Bases: FerrumVisualizer

Visualize the distribution of per-fold cross-validation scores.

Wraps cv_scores_chart in the sklearn visualizer protocol. After fit(X, y), _metrics contains test_mean (mean test-fold score across all folds) and test_std (standard deviation of test-fold scores).

Parameters:

Name Type Description Default
model Any

Unfitted or fitted sklearn-compatible estimator.

required
cv int

Number of cross-validation folds.

5
scoring str or callable

Sklearn scoring string or callable. Defaults to the estimator's own score method when None.

None
kind ('box', 'bar', 'strip')

Chart geometry used to display the fold-score distributions.

"box"
split ('both', 'test', 'train')

Which CV splits to include in the chart. "both" shows train and test folds side by side; "test" or "train" shows only one.

"both"
random_state int

Seed forwarded to ModelSource for reproducible CV splits (ChaCha8 RNG).

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import RandomForestClassifier
>>> viz = fm.CVScoresVisualizer(
...     RandomForestClassifier(n_estimators=100), cv=10, kind="box"
... ).fit(X_train, y_train)
>>> chart = viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

AlphaSelectionVisualizer

Bases: FerrumVisualizer

Visualize cross-validated scores over a regularization-strength grid.

Wraps alpha_selection_chart in the sklearn visualizer protocol. Designed for regularized regressors such as Ridge, Lasso, and ElasticNet — estimators that expose an alpha hyperparameter controlling L1/L2 penalty strength. For each value in alphas, cross-validation produces a mean score; the alpha that maximises the mean test score is stored as best_alpha in _metrics, and the corresponding score as best_score.

Parameters:

Name Type Description Default
model Any

Unfitted regularized regressor with an alpha hyperparameter (e.g. sklearn.linear_model.Ridge, Lasso, ElasticNet). Passing an estimator without an alpha parameter will raise at fit time.

required
alphas array - like

Grid of regularization-strength values to evaluate. Passed directly to the underlying alpha_selection compute; log-spaced grids (e.g. np.logspace(-4, 4, 50)) are typical.

required
cv int

Number of cross-validation folds.

5
scoring str or callable

Sklearn scoring string or callable. Defaults to the estimator's own score method when None.

None
log_scale bool

Whether to render the x-axis (alpha values) on a log scale. Defaults to True because alpha grids are almost always log-spaced.

True
highlight_best bool

When True, draws a vertical rule at the alpha value that maximises the mean test score.

True
random_state int

Seed forwarded to ModelSource for reproducible CV splits (ChaCha8 RNG).

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import Ridge
>>> import numpy as np
>>> viz = fm.AlphaSelectionVisualizer(
...     Ridge(), alphas=np.logspace(-4, 4, 40), cv=5
... ).fit(X_train, y_train)
>>> chart = viz.show()

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

SilhouetteVisualizer

Bases: FerrumVisualizer

Rousseeuw silhouette plot for a fitted clusterer.

Computes per-sample silhouette coefficients via ModelSource.silhouette and renders a horizontal bar chart sorted by cluster, one bar per sample. Records mean_silhouette — the grand mean silhouette coefficient averaged across all samples — as the headline metric.

Takes a fitted estimator (not a class); for the k-sweep variant use ElbowVisualizer.

Parameters:

Name Type Description Default
model Any

Fitted clustering estimator (e.g. sklearn.cluster.KMeans instance) that exposes labels_ (and optionally cluster_centers_).

required
random_state int

Seed forwarded to the underlying ModelSource. Ignored when the silhouette computation is deterministic.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> model = KMeans(n_clusters=3, random_state=0).fit(X)
>>> viz = fm.SilhouetteVisualizer(model).fit(X)
>>> viz.show()
>>> viz._metrics["mean_silhouette"]

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ElbowVisualizer

Bases: FerrumVisualizer

Elbow / score sweep over a range of k for a clusterer class.

Unlike other ferrum visualizers, ElbowVisualizer takes a model class (e.g. KMeans) — not a fitted instance — and constructs and fits one model per k value inside its own fit() override. The ModelSource round-trip is skipped entirely; per-k models are transient and discarded after their score is recorded. Renders a score-vs-k line chart.

Records best_k — the integer k whose score is optimal for the selected metric — as the headline metric. For "distortion" the optimal score is the minimum; for "silhouette" and "calinski_harabasz" it is the maximum (higher is better).

Parameters:

Name Type Description Default
model_class type

Uninstantiated clustering class (e.g. sklearn.cluster.KMeans). Must accept n_clusters, random_state, and n_init keyword arguments and expose .inertia_ after fitting (for the "distortion" metric) or .labels_ (for "silhouette" / "calinski_harabasz").

required
ks sequence of int

The candidate k values to sweep (e.g. range(2, 11)). Note that "silhouette" and "calinski_harabasz" are undefined at k == 1 — such entries are silently skipped from the score sweep.

required
metric ('distortion', 'silhouette', 'calinski_harabasz')

Score to optimize. "distortion" (sum of squared distances to the nearest centroid, i.e. .inertia_) is minimized; "silhouette" (mean Rousseeuw silhouette coefficient) and "calinski_harabasz" (Calinski–Harabasz / Variance Ratio Criterion) are maximized. Any other value raises ValueError.

"distortion"
random_state int

Integer seed passed as random_state to every per-k model instantiation. When None, seed 0 is used.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> viz = fm.ElbowVisualizer(KMeans, ks=range(2, 9)).fit(X)
>>> viz.show()
>>> viz._metrics["best_k"]

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ManifoldVisualizer

Bases: FerrumVisualizer

Low-dimensional manifold-embedding scatter (UMAP / t-SNE / PCA).

Projects the input data to two dimensions via the method selected by method and renders a point chart with axes dim_0 / dim_1 colored by cluster label. The embedding is computed by ModelSource.embeddings and cached so _build_chart does not recompute it.

Takes a fitted clustering estimator whose labels_ attribute is used to color points. Pass model=None only if you override fit in a subclass and supply labels_ by other means.

Records n_samples — the number of rows in the embedding — as the headline metric.

Parameters:

Name Type Description Default
model Any

Fitted clustering estimator (e.g. KMeans instance) that exposes labels_. Defaults to None (for subclass overrides).

None
method str

Embedding algorithm forwarded to ModelSource.embeddings. Typical values are "umap", "tsne", and "pca".

"umap"
random_state int

Seed forwarded to the underlying ModelSource. Controls reproducibility for stochastic embeddings such as UMAP and t-SNE.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> model = KMeans(n_clusters=4, random_state=0).fit(X)
>>> viz = fm.ManifoldVisualizer(model, method="umap").fit(X)
>>> viz.show()
>>> viz._metrics["n_samples"]

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

InterclusterDistanceVisualizer

Bases: FerrumVisualizer

Cluster-center 2D embedding with cluster-size bubble overlay.

Projects cluster centers into 2D via the algorithm selected by method and renders a bubble chart where each bubble represents one cluster; bubble area encodes the cluster's sample count. Built on ferrum.intercluster_distance_chart.

Takes a fitted clustering estimator that exposes either n_clusters or cluster_centers_ so the number of clusters can be inferred.

Records max_intercluster_dist — the largest Euclidean distance from any cluster center to the centroid of all centers in the 2D embedding — as a rough measure of how spread-out the clusters are.

Parameters:

Name Type Description Default
model Any

Fitted clustering estimator (e.g. KMeans instance) that exposes n_clusters or cluster_centers_.

required
method str

Dimensionality-reduction algorithm forwarded to ModelSource.intercluster_distance. Typical values include "mds" and "tsne".

"mds"
random_state int

Seed forwarded to the underlying ModelSource. Controls reproducibility for stochastic layout algorithms.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> model = KMeans(n_clusters=5, random_state=0).fit(X)
>>> viz = fm.InterclusterDistanceVisualizer(model).fit(X)
>>> viz.show()
>>> viz._metrics["max_intercluster_dist"]

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

PCAVarianceVisualizer

Bases: FerrumVisualizer

PCA scree plot showing explained variance per principal component.

Retrieves per-component explained-variance ratios via ModelSource.pca_variance and renders a bar chart of explained-variance ratio vs. component index, optionally limited to the first n_components components. Built on ferrum.pca_scree_chart.

Takes a fitted decomposition estimator (e.g. sklearn.decomposition.PCA instance) that exposes explained_variance_ratio_.

Records first_component_var — the fraction of total variance captured by the first principal component — as the headline metric.

Parameters:

Name Type Description Default
model Any

Fitted decomposition estimator (e.g. PCA instance) that exposes explained_variance_ratio_.

required
n_components int

Number of components to display in the scree plot. When None, all components present in the model are shown.

None
random_state int

Seed forwarded to the underlying ModelSource. Ignored when the PCA variance computation is deterministic.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> from sklearn.decomposition import PCA
>>> model = PCA(n_components=10).fit(X)
>>> viz = fm.PCAVarianceVisualizer(model, n_components=5).fit(X)
>>> viz.show()
>>> viz._metrics["first_component_var"]

fit

fit(X: Any, y: Any = None) -> 'FerrumVisualizer'

Materialize derived data from X / y and build the chart.

Constructs a ModelSource from the wrapped model, calls _materialize to populate _metrics, then _build_chart to assemble the ferrum Chart. Returns self for method chaining.

Parameters:

Name Type Description Default
X array - like

Feature matrix. Accepted types match ModelSource.__init__.

required
y array - like

Target vector. Required by most classification / regression diagnostics; optional for unsupervised variants.

None

Returns:

Type Description
FerrumVisualizer

self — the fitted visualizer instance.

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

Rank1DVisualizer

Bases: FerrumVisualizer

Rank features by a univariate statistic and display as a bar chart.

A no-model visualizer (model=None) that computes a scalar score for each feature column and renders them as a ranked horizontal or vertical bar chart. fit is overridden directly — the base-class ModelSource round-trip is bypassed entirely.

Records top_feature_score (the score of the highest-ranked feature) in _metrics.

Parameters:

Name Type Description Default
algorithm ('shapiro', 'variance', 'covariance')

Scoring algorithm.

  • "shapiro" — Shapiro-Wilk W statistic (normality score).
  • "variance" — variance of each feature column.
  • "covariance" — absolute covariance with the target y. Requires y to be passed at fit time; raises ValueError when y is None.
"shapiro"
orient ('horizontal', 'vertical')

Bar orientation of the resulting chart.

"horizontal"
top_k int

If given, display only the top top_k features. None shows all features.

None
color_field str

Column name forwarded to the chart's color encoding. None produces a single-color chart.

None
random_state int

Accepted for API symmetry with model-backed visualizers but intentionally never consumed — this visualizer bypasses ModelSource entirely. Documented as a permanent no-op so callers that script over visualizers don't have to special-case which ones accept the kwarg.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Raises:

Type Description
ValueError

When algorithm="covariance" and y is None at fit time.

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.read_csv("wine.csv")
>>> X, y = df.drop("target"), df["target"]
>>> viz = fm.Rank1DVisualizer(algorithm="variance").fit(X)
>>> viz.show()

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

Rank2DVisualizer

Bases: FerrumVisualizer

Rank feature pairs by pairwise correlation and display as a heatmap.

A no-model visualizer (model=None) that computes an N×N correlation matrix and renders it as an annotated heatmap. fit is overridden directly — the base-class ModelSource round-trip is bypassed entirely.

The "kendall" algorithm routes pairwise computation through ferrum._core.kendall_tau_b (Rust) for performance.

Records max_abs_corr (the largest absolute off-diagonal correlation value) in _metrics — useful for detecting multicollinearity at a glance.

Parameters:

Name Type Description Default
algorithm ('pearson', 'spearman', 'kendall', 'covariance')

Pairwise association measure.

  • "pearson" — Pearson linear correlation coefficient.
  • "spearman" — Spearman rank correlation.
  • "kendall" — Kendall tau-b, computed via ferrum._core.kendall_tau_b for performance.
  • "covariance" — raw covariance (not normalized to [-1, 1]).
"pearson"
annot bool

Whether to annotate each heatmap cell with its numeric value.

True
random_state int

Accepted for API symmetry with model-backed visualizers but intentionally never consumed — this visualizer bypasses ModelSource entirely. Documented as a permanent no-op so callers that script over visualizers don't have to special-case which ones accept the kwarg.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.read_csv("wine.csv")
>>> X = df.drop("target")
>>> viz = fm.Rank2DVisualizer(algorithm="spearman").fit(X)
>>> viz.show()

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

ParallelCoordinatesVisualizer

Bases: FerrumVisualizer

Visualize multivariate samples as a parallel-coordinates chart.

A no-model visualizer (model=None) that draws one polyline per sample across a set of parallel vertical axes (one per feature). fit is overridden directly — the base-class ModelSource round-trip is bypassed entirely.

Records n_samples and n_features in _metrics so the repr surfaces the chart's shape.

Parameters:

Name Type Description Default
features list of str

Subset of column names to include as axes. When None, all non-hue columns are used.

None
hue str

Column name used to color-encode each sample line. None produces a single-color chart unless fit(X, y) is called with y — in that case y is attached as the hue column automatically.

None
rescale ('minmax', 'zscore', None)

Per-axis normalization applied before plotting.

  • "minmax" — rescale each axis to [0, 1].
  • "zscore" — standardize each axis to zero mean, unit variance.
  • None — no rescaling; raw values are plotted.
"minmax"
alpha float

Opacity of each sample line (0 = fully transparent, 1 = opaque).

0.5
random_state int

Accepted for API symmetry with model-backed visualizers but intentionally never consumed — this visualizer bypasses ModelSource entirely. Documented as a permanent no-op so callers that script over visualizers don't have to special-case which ones accept the kwarg.

None
theme Theme

Per-chart theme override. Falls back to the global default when None.

None

Examples:

>>> import ferrum as fm
>>> import polars as pl
>>> df = pl.read_csv("iris.csv")
>>> viz = fm.ParallelCoordinatesVisualizer(hue="species", rescale="minmax")
>>> viz.fit(df.drop("species"), df["species"])
>>> viz.show()

score

score(X: Any, y: Any) -> float

Returns 0.0 for visualizers that do not compute a test-set score.

Subclasses that wrap a fitted estimator override this to return an appropriate metric (e.g. roc_auc_score for ROCVisualizer, r2_score for ResidualsVisualizer). The base implementation returns 0.0 so that no-model / exploratory visualizers satisfy the sklearn visualizer protocol without raising.

Parameters:

Name Type Description Default
X array - like

Feature matrix, same type accepted by fit.

required
y array - like

True target values.

required

Returns:

Type Description
float

0.0 for the base class; a meaningful scalar for subclasses that override this method.

show

show() -> Any

Return the ferrum Chart for this visualizer.

Must be called after fit; raises RuntimeError otherwise. The returned Chart can be rendered in a notebook (_repr_svg_), saved with .save(path), or composed with other charts via + / /.

Returns:

Type Description
Chart

The assembled diagnostic chart.

Raises:

Type Description
RuntimeError

If fit has not been called yet.

X

Bases: ChannelBase

Positional X channel — maps a field to the horizontal axis.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type: quantitative, nominal, ordinal, temporal. Inferred from the column dtype when omitted.

"Q"
bin bool or Bin

If truthy, bin the field before mapping. Pass a Bin(...) instance to control bin width or count; True uses automatic binning.

required
aggregate str

Aggregation operation applied before mapping (e.g. "mean", "sum", "count").

required
scale Scale

Explicit scale override (e.g. LogScale(), LinearScale()).

required
title str

Axis title override. When omitted the field name is used.

required
Notes

axis, legend, sort, stack, and impute kwargs are accepted and forwarded to the EncodingSpec; per-channel axis/legend customization depends on Rust-side support for the channel.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x=fm.X("hp", type_="Q"))
>>> fm.Chart(df).encode(x=fm.X("hp", bin=True))
>>> fm.Chart(df).encode(x=fm.X("hp", aggregate="mean"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Y

Bases: ChannelBase

Positional Y channel — maps a field to the vertical axis.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type: quantitative, nominal, ordinal, temporal. Inferred from the column dtype when omitted.

"Q"
bin bool or Bin

If truthy, bin the field before mapping. Pass a Bin(...) instance to control bin width or count; True uses automatic binning.

required
aggregate str

Aggregation operation applied before mapping (e.g. "mean", "sum", "count").

required
scale Scale

Explicit scale override (e.g. LogScale(), LinearScale()).

required
title str

Axis title override. When omitted the field name is used.

required
Notes

axis, legend, sort, stack, and impute kwargs are accepted and forwarded to the EncodingSpec; per-channel axis/legend customization depends on Rust-side support for the channel.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(y=fm.Y("mpg", type_="Q"))
>>> fm.Chart(df).encode(y=fm.Y("mpg", aggregate="mean"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

X2

Bases: ChannelBase

Secondary X channel — maps a field to the second x position.

Used for ranged marks (rule, rect, ribbon) where a mark spans from x to x2 along the horizontal axis.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

bin, aggregate, scale, and title kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x=fm.X("start"), x2=fm.X2("end"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Y2

Bases: ChannelBase

Secondary Y channel — maps a field to the second y position.

Used for ranged marks (rule, rect, ribbon) where a mark spans from y to y2 along the vertical axis.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

bin, aggregate, scale, and title kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(y=fm.Y("low"), y2=fm.Y2("high"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

XError

Bases: ChannelBase

X-axis error channel — maps a field to symmetric error around x.

The error bar extends x ± x_error along the horizontal axis.

Parameters:

Name Type Description Default
field str

Column name whose values are the error magnitude.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="mean_hp", x_error=fm.XError("ci_hp"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

YError

Bases: ChannelBase

Y-axis error channel — maps a field to symmetric error around y.

The error bar extends y ± y_error along the vertical axis.

Parameters:

Name Type Description Default
field str

Column name whose values are the error magnitude.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(y="mean_mpg", y_error=fm.YError("ci_mpg"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

XError2

Bases: ChannelBase

Secondary x-axis error channel — for asymmetric error bounds.

When paired with XError, sets the upper bound of the error bar independently of the lower bound, enabling asymmetric error bars.

Parameters:

Name Type Description Default
field str

Column name whose values are the upper-side error magnitude.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(
...     x="mean_hp",
...     x_error=fm.XError("err_low"),
...     x_error2=fm.XError2("err_high"),
... )

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

YError2

Bases: ChannelBase

Secondary y-axis error channel — for asymmetric error bounds.

When paired with YError, sets the upper bound of the error bar independently of the lower bound, enabling asymmetric error bars.

Parameters:

Name Type Description Default
field str

Column name whose values are the upper-side error magnitude.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(
...     y="mean_mpg",
...     y_error=fm.YError("err_low"),
...     y_error2=fm.YError2("err_high"),
... )

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Theta

Bases: ChannelBase

Polar angle channel — maps a field to the angular position in polar coords.

Typically used with arc or pie marks; the field values determine the sweep angle of each arc segment.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
stack bool or str

Stacking behaviour for arc segments. True enables stacking; False disables it; "normalize" produces percentage arcs.

required
Notes

Requires CoordPolar() on the chart to activate polar rendering; without it the channel is registered but the mark renders in Cartesian space.

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(theta=fm.Theta("count", stack=True))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Radius

Bases: ChannelBase

Polar radius channel — maps a field to the radial position in polar coords.

Controls how far each mark is placed from the center of the polar plot.

Parameters:

Name Type Description Default
field str

Column name in the input DataFrame.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Requires CoordPolar() on the chart to activate polar rendering; without it the channel is registered but the mark renders in Cartesian space.

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(theta=fm.Theta("count"), radius=fm.Radius("distance"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Color

Bases: ChannelBase

Color encoding channel — maps a field to mark color (fill and stroke).

Parameters:

Name Type Description Default
field str

Column name to map to color.

None
type_ ('Q', 'N', 'O', 'T')

Data type: quantitative, nominal, ordinal, temporal. Inferred from the column dtype when omitted.

"Q"
scheme str

Named color scheme for categorical data (e.g. "tableau10", "set1"). Only honored for the Color channel; other channels treat this kwarg as a no-op.

required
scale Scale

Explicit scale override (e.g. ColorScale.Continuous("viridis")).

required
title str

Legend title override. When omitted the field name is used.

required
Notes

legend is honored: passing legend={"disabled": True}, legend=None, or legend=False suppresses the color legend in the rendered SVG. sort is honored: pass a list of strings to set the explicit domain order for the color scale. condition is accepted but reserved for future use.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", color=fm.Color("cyl"))
>>> fm.Chart(df).encode(x="hp", y="mpg", color=fm.Color("origin", scheme="set1"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Fill

Bases: ChannelBase

Fill color channel — maps a field to filled-mark fill color.

Distinct from stroke, which controls only the outline color. When both Fill and Color are encoded, Fill takes precedence for the interior of the mark.

Parameters:

Name Type Description Default
field str

Column name to map to fill color.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", fill=fm.Fill("origin"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Stroke

Bases: ChannelBase

Stroke color channel — maps a field to mark stroke (outline) color.

Distinct from fill, which controls only the interior color.

Parameters:

Name Type Description Default
field str

Column name to map to stroke color.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", stroke=fm.Stroke("origin"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Opacity

Bases: ChannelBase

Opacity channel — maps a field to overall mark opacity.

Controls both fill and stroke opacity simultaneously. Values are mapped to the range [0, 1].

Parameters:

Name Type Description Default
field str

Column name to map to opacity.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
scale Scale

Explicit scale override.

required
title str

Legend title override.

required
Notes

legend and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", opacity=fm.Opacity("year"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

FillOpacity

Bases: ChannelBase

Fill-opacity channel — maps a field to fill opacity.

Independent of stroke opacity; controls only how transparent the interior of a mark is. Values are mapped to the range [0, 1].

Parameters:

Name Type Description Default
field str

Column name to map to fill opacity.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", fill_opacity=fm.FillOpacity("density"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

StrokeOpacity

Bases: ChannelBase

Stroke-opacity channel — maps a field to stroke opacity.

Independent of fill opacity; controls only how transparent the outline of a mark is. Values are mapped to the range [0, 1].

Parameters:

Name Type Description Default
field str

Column name to map to stroke opacity.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", stroke_opacity=fm.StrokeOpacity("year"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

StrokeWidth

Bases: ChannelBase

Stroke-width channel — maps a field to stroke width in pixels.

Larger values produce thicker mark outlines.

Parameters:

Name Type Description Default
field str

Column name to map to stroke width.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", stroke_width=fm.StrokeWidth("importance"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

StrokeDash

Bases: ChannelBase

Stroke-dash channel — maps a field to a dash pattern.

Each level of the field maps to a distinct dash-gap pattern for the mark stroke (e.g. solid, dashed, dotted).

Parameters:

Name Type Description Default
field str

Column name (typically nominal or ordinal) to map to dash pattern.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", stroke_dash=fm.StrokeDash("group", type_="N"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Size

Bases: ChannelBase

Size channel — maps a field to mark size (point area in square pixels).

For point marks the size value corresponds to the area of the mark in square pixels.

Parameters:

Name Type Description Default
field str

Column name to map to size.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
scale Scale

Explicit scale override.

required
title str

Legend title override.

required
Notes

legend and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", size=fm.Size("weight"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Shape

Bases: ChannelBase

Shape channel — maps a categorical field to point shape.

Supported shapes include "circle", "square", "triangle", "cross", "diamond", and "star".

Parameters:

Name Type Description Default
field str

Column name (should be nominal or ordinal) to map to shape.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted; "N" is the most common choice.

"Q"
scale Scale

Explicit scale override.

required
title str

Legend title override.

required
Notes

legend and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", shape=fm.Shape("origin", type_="N"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Angle

Bases: ChannelBase

Angle channel — maps a field to mark rotation in degrees.

Rotates each mark around its center point. A value of 0 is upright; values increase clockwise.

Parameters:

Name Type Description Default
field str

Column name to map to rotation angle.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

scale, title, legend, and condition kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", angle=fm.Angle("direction"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Text

Bases: ChannelBase

Text channel — maps a field to text-mark content.

Renders each data point's field value as a text label. Primarily used with the mark_text mark.

Parameters:

Name Type Description Default
field str

Column name whose values are rendered as text.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
format str

Number or date format string (e.g. ".2f" for two decimal places, "%b %Y" for abbreviated month and year).

required
formatType str

Format type hint; "number" or "time". Used in combination with format.

required
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", text=fm.Text("label"))
>>> fm.Chart(df).encode(x="x", y="y", text=fm.Text("value", format=".1f"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Detail

Bases: ChannelBase

Detail channel — adds a field to the encoding without a visual variable.

Groups marks by the levels of the field without mapping those levels to any visual property (color, size, shape, etc.). Useful for drawing one line per group in a line chart.

Parameters:

Name Type Description Default
field str

Column name to group by.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="year", y="value", detail=fm.Detail("series"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Tooltip

Bases: ChannelBase

Tooltip channel — specifies which fields appear in the hover tooltip.

Accepts one or more field names (as strings or TooltipField helpers) that are shown when the viewer hovers over a mark in an interactive renderer.

Parameters:

Name Type Description Default
*fields str or TooltipField

One or more column names or TooltipField(...) instances to include in the tooltip. Passing a single string is equivalent to Tooltip(TooltipField(field)).

()
Notes

type kwarg is accepted but is reserved for future use (no-op today) — it triggers a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg",
...     tooltip=fm.Tooltip("hp", "mpg"))
>>> fm.Chart(df).encode(x="hp", y="mpg",
...     tooltip=fm.Tooltip("hp", fm.TooltipField("cyl", title="Cylinders")))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

TooltipField

Bases: ChannelBase

Helper for an individual tooltip field with optional title and format.

Used inside Tooltip(*fields) to customise how a single column is displayed in the hover tooltip. Not used as a top-level encoding channel.

Parameters:

Name Type Description Default
field str

Column name.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
title str

Custom tooltip label for this field.

required
format str

Number or date format string (e.g. ".1f", "%Y-%m-%d").

required
formatType str

Format type hint; "number" or "time".

required
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg",
...     tooltip=fm.Tooltip("hp", fm.TooltipField("mpg", title="MPG", format=".1f")))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Href

Bases: ChannelBase

URL-link channel — maps a field to a clickable URL.

When the chart is rendered in an interactive renderer, marks become clickable hyperlinks pointing to the URL stored in field.

Parameters:

Name Type Description Default
field str

Column name containing the URL string for each mark.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning. Interactive renderers only; SVG export does not embed hyperlinks.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", href=fm.Href("url"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Description

Bases: ChannelBase

Accessibility description channel — maps a field to per-mark alt text.

The description text is used by screen readers and other accessibility tools to describe each individual mark.

Parameters:

Name Type Description Default
field str

Column name whose values are used as the accessibility description.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", description=fm.Description("alt_text"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Key

Bases: ChannelBase

Key channel — maps a field to a unique key per mark.

Provides a stable identity for each mark when joining across data updates (e.g. animated transitions or streaming data).

Parameters:

Name Type Description Default
field str

Column name whose values uniquely identify each mark.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted.

"Q"
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="x", y="y", key=fm.Key("id"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Url

Bases: ChannelBase

Image URL channel — maps a field to a base64 data URL for mark_image tiles.

Each row provides a data:image/...;base64,<payload> URL that is placed as an image tile at the position given by the x and y encodings. Used exclusively with :meth:~ferrum.Chart.mark_image.

Parameters:

Name Type Description Default
field str

Column name containing the base64 data URL for each tile.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted (typically "N" for string columns).

"Q"

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).mark_image().encode(x="x:Q", y="y:Q", url=fm.Url("data_url"))

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

Facet

Bases: ChannelBase

Facet channel — splits a chart into a grid by levels of a field.

Wraps the chart into a faceted layout where each panel shows data for one level of the facet field. Pass this channel object to Chart.encode(facet=...).

Parameters:

Name Type Description Default
field str

Column name to facet by.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted; "N" or "O" are the most common choices.

"Q"
title str

Facet panel title override. When omitted the field name is used.

required
Notes

columns (number of facets per row) is accepted as a kwarg but is reserved for future use (no-op today) — it triggers a one-time deprecation warning. If you need column-wrap control today, use Chart.facet(ncols=N) directly.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", facet=fm.Facet("species")).mark_point()
>>> fm.Chart(df).encode(x="hp", y="mpg").mark_point().facet("species", ncols=3)

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

FacetRow

Bases: ChannelBase

Facet-row channel — splits a chart into rows by levels of a field.

Pass this channel object to Chart.encode(facet_row=...) to create a row-faceted layout where each row shows data for one level of the field.

Parameters:

Name Type Description Default
field str

Column name to facet rows by.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted; "N" or "O" are the most common choices.

"Q"
title str

Row-facet title override. When omitted the field name is used.

required
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", facet_row=fm.FacetRow("year")).mark_point()

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

FacetCol

Bases: ChannelBase

Facet-column channel — splits a chart into columns by levels of a field.

Pass this channel object to Chart.encode(facet_col=...) to create a column-faceted layout where each column shows data for one level of the field.

Parameters:

Name Type Description Default
field str

Column name to facet columns by.

None
type_ ('Q', 'N', 'O', 'T')

Data type. Inferred from the column dtype when omitted; "N" or "O" are the most common choices.

"Q"
title str

Column-facet title override. When omitted the field name is used.

required
Notes

Other kwargs are accepted but are reserved for future use (no-op today) — they trigger a one-time deprecation warning.

Examples:

>>> import ferrum as fm
>>> fm.Chart(df).encode(x="hp", y="mpg", facet_col=fm.FacetCol("species")).mark_point()

to_encoding_spec_dict

to_encoding_spec_dict() -> dict

Return kwargs for the Rust EncodingSpec constructor / serde JSON.

to_implicit_transforms

to_implicit_transforms() -> list

Return a list of transform objects derived from kwargs (bin, aggregate).

compute_layout

compute_layout(spec, *, viewport: tuple[float, float], x_tick_labels: list[str], y_tick_labels: list[str], x_title: str | None = None, y_title: str | None = None, facet_groups: list[tuple[str, str, int]] | None = None, legend_entries: list[tuple[str, str]] | None = None, legend_orient: str = 'right', label_angle: float | None = None) -> dict

Compute the layout plan (panel sizes, margins) for a chart spec.

Examples:

>>> import ferrum as fm
>>> layout = fm.compute_layout(chart_spec_json, viewport_json)

process_batch

process_batch(data: Any) -> Any

Convert a Python record batch through the ferrum transform pipeline.

Examples:

>>> import ferrum as fm
>>> result = fm.process_batch(record_batch)

render_png

render_png(spec: ChartSpec, data: Any, *, viewport: tuple[float, float], theme: Optional[dict] = None, config: Optional[dict] = None) -> bytes

Render a chart spec to PNG bytes.

Examples:

>>> import ferrum as fm
>>> png_bytes = fm.render_png(chart_spec_json, layout_json, data_batch)

render_svg

render_svg(spec: ChartSpec, data: Any, *, viewport: tuple[float, float], theme: Optional[dict] = None, config: Optional[dict] = None) -> str

Render a chart spec to an SVG string.

Examples:

>>> import ferrum as fm
>>> svg = fm.render_svg(chart_spec_json, layout_json, data_batch)

compose_svg_horizontal

compose_svg_horizontal(svgs: list[str], *, spacing: float = 10.0, align: Literal['top', 'center', 'bottom'] = 'top') -> str

Lay out SVG panels side-by-side.

Examples:

>>> import ferrum as fm
>>> combined = fm.compose_svg_horizontal([svg1, svg2], spacing=10)

compose_svg_vertical

compose_svg_vertical(svgs: list[str], *, spacing: float = 10.0, align: Literal['left', 'center', 'right'] = 'left') -> str

Stack SVG panels top-to-bottom.

Examples:

>>> import ferrum as fm
>>> combined = fm.compose_svg_vertical([svg1, svg2], spacing=10)

compose_svg_grid

compose_svg_grid(cells: list[str | None], *, rows: int, cols: int, row_ratios: list[float], col_ratios: list[float], spacing: float = 10.0, share_x: list[list[int]] = ..., share_y: list[list[int]] = ...) -> str

Arrange SVG panels in a grid.

Examples:

>>> import ferrum as fm
>>> combined = fm.compose_svg_grid([[svg1, svg2], [svg3, svg4]], spacing=10)

continuous_palette

continuous_palette(name: str)

Look up a built-in continuous colormap by name.

Parameters:

Name Type Description Default
name ('viridis', 'plasma', 'magma', 'inferno', 'cividis')

Built-in colormap name.

"viridis"

Returns:

Type Description
ContinuousScheme

A ferrum continuous scheme suitable for Color(scale=...).

Raises:

Type Description
ValueError

If name is not one of the built-in colormaps.

Examples:

>>> import ferrum as fm
>>> scheme = fm.continuous_palette("viridis")
>>> fm.Chart(df).encode(x="x", y="y", color=fm.Color("val", scale=scheme))

set_default_theme

set_default_theme(theme: Theme) -> AbstractContextManager

Set the process-default theme for all subsequent charts.

The returned object is a context manager. Use it with with to scope the default to a block (previous default is restored on __exit__). Fire-and-forget usage (without with) is also supported.

Per-chart Chart.theme(t) always overrides this process default.

Parameters:

Name Type Description Default
theme Theme

Theme to install as the process default.

required

Returns:

Type Description
AbstractContextManager

Context manager that restores the prior default on __exit__.

Raises:

Type Description
TypeError

If theme is not a Theme instance.

Examples:

Fire-and-forget:

>>> import ferrum as fm
>>> fm.set_default_theme(fm.themes.dark)

Scoped to a block:

>>> with fm.set_default_theme(fm.themes.dark):
...     chart = fm.Chart(df).mark_point().encode(x="hp", y="mpg")

get_default_theme

get_default_theme() -> Theme

Return the current process-default theme.

Returns:

Type Description
Theme

The currently active process-default theme. Starts as ferrum.themes.default (Rust renderer defaults); changes after each set_default_theme() call.

Examples:

>>> import ferrum as fm
>>> fm.get_default_theme()
Theme()

theme_context

theme_context(theme: Theme) -> AbstractContextManager

Scope a theme to a with block — alias for set_default_theme().

Prefer this spelling over set_default_theme() when the intent is always context-manager usage (e.g. in tests or notebook cells).

Parameters:

Name Type Description Default
theme Theme

Theme to activate for the duration of the with block.

required

Returns:

Type Description
AbstractContextManager

Context manager; restores the prior default on __exit__.

Examples:

>>> import ferrum as fm
>>> with fm.theme_context(fm.themes.dark):
...     chart = fm.Chart(df).mark_point().encode(x="hp", y="mpg")

annotate_hline

annotate_hline(y: float, *, label: Optional[str] = None, stroke: Optional[str] = None, stroke_dash=None) -> Chart

Horizontal reference line at a fixed y position.

Returns a single-mark Chart suitable for | / & concatenation composition; for true overlay/layer, use + with a chart that shares the same DataFrame.

Parameters:

Name Type Description Default
y float

Y position of the line in data coordinates.

required
label str

Reserved for future use (no-op today).

None
stroke str

Line color as a CSS color string. Defaults to the mark default when omitted.

None
stroke_dash list of float

SVG dash array, e.g. [4, 4] for evenly dashed.

None

Returns:

Type Description
Chart

Annotation chart suitable for | / & composition.

Examples:

>>> import ferrum as fm
>>> ref = fm.annotate_hline(y=0.0, stroke="red", stroke_dash=[4, 4])
>>> chart = fm.Chart(df).encode(x="t", y="r").mark_line() & ref

annotate_vline

annotate_vline(x: float, *, label: Optional[str] = None, stroke: Optional[str] = None, stroke_dash=None) -> Chart

Vertical reference line at a fixed x position.

Returns a single-mark Chart suitable for | / & concatenation composition; for true overlay/layer, use + with a chart that shares the same DataFrame.

Parameters:

Name Type Description Default
x float

X position of the line in data coordinates.

required
label str

Reserved for future use (no-op today).

None
stroke str

Line color as a CSS color string.

None
stroke_dash list of float

SVG dash array, e.g. [4, 4].

None

Returns:

Type Description
Chart

Annotation chart suitable for | / & composition.

Examples:

>>> import ferrum as fm
>>> ref = fm.annotate_vline(x=2020, stroke="#888")
>>> chart = fm.Chart(df).encode(x="year", y="val").mark_line() & ref

annotate_rect

annotate_rect(x1: float, x2: float, y1: float, y2: float, *, fill: Optional[str] = None, opacity: float = 0.1, label: Optional[str] = None) -> Chart

Shaded rectangle region spanning (x1, y1) to (x2, y2).

Returns a mark_rect annotation chart for | / & concatenation composition; for true overlay/layer, use + with a chart that shares the same DataFrame.

Parameters:

Name Type Description Default
x1 float

Left x boundary in data coordinates.

required
x2 float

Right x boundary in data coordinates.

required
y1 float

Bottom y boundary in data coordinates.

required
y2 float

Top y boundary in data coordinates.

required
fill str

Fill color as a CSS color string.

None
opacity float

Fill opacity in [0, 1].

0.1
label str

Reserved for future use (no-op today).

None

Returns:

Type Description
Chart

Annotation chart suitable for | / & composition.

Examples:

>>> import ferrum as fm
>>> shade = fm.annotate_rect(x1=2018, x2=2020, y1=0, y2=100,
...                          fill="#ffcc00", opacity=0.2)
>>> chart = fm.Chart(df).encode(x="year", y="val").mark_line() & shade

annotate_text

annotate_text(x: float, y: float, text: str, *, dx: float = 0, dy: float = 0, align: str = 'center', baseline: str = 'middle', font_size: Optional[float] = None, color: Optional[str] = None, angle: Optional[float] = None) -> Chart

Free-floating text annotation at a fixed (x, y) position.

Returns a mark_text chart for | / & concatenation composition; for true overlay/layer, use + with a chart that shares the same DataFrame.

Parameters:

Name Type Description Default
x float

X position in data coordinates.

required
y float

Y position in data coordinates.

required
text str

Text string to display.

required
dx float

Horizontal pixel offset from (x, y).

0
dy float

Vertical pixel offset from (x, y).

0
align str

Horizontal text alignment (SVG text-anchor): "left", "center", or "right".

"center"
baseline str

Vertical text baseline: "top", "middle", or "bottom".

"middle"
font_size float

Font size in points.

None
color str

Text fill color as a CSS color string.

None
angle float

Rotation angle in degrees (clockwise).

None

Returns:

Type Description
Chart

Annotation chart suitable for | / & composition.

Examples:

>>> import ferrum as fm
>>> label = fm.annotate_text(x=2020, y=95, text="peak", dy=-8,
...                          color="#333", font_size=11)
>>> chart = fm.Chart(df).encode(x="year", y="val").mark_line() & label

annotate_arrow

annotate_arrow(x1: float, y1: float, x2: float, y2: float, *, label: Optional[str] = None, label_side: str = 'start', stroke: Optional[str] = None) -> Chart

Draw an arrow from (x1, y1) to (x2, y2) with an optional text label.

Composes a mark_segment (the arrow shaft) with an optional annotate_text placed at the label_side endpoint.

Parameters:

Name Type Description Default
x1 float

Horizontal data coordinate of the arrow start.

required
y1 float

Vertical data coordinate of the arrow start.

required
x2 float

Horizontal data coordinate of the arrow end (tip).

required
y2 float

Vertical data coordinate of the arrow end (tip).

required
label str

Text to display alongside the arrow. When omitted, no text is rendered.

None
label_side ('start', 'end')

Which end of the arrow to place the label. "start" anchors the text at (x1, y1); "end" places it at (x2, y2).

"start"
stroke str

Hex colour string for the arrow line (e.g. "#ff0000"). Inherits the theme's foreground colour when omitted.

None

Returns:

Type Description
Chart

Layered chart containing the arrow segment and, when label is provided, the annotation text.

Examples:

Simple unlabelled arrow:

>>> import ferrum as fm
>>> fm.annotate_arrow(0.1, 0.5, 0.8, 0.9)

Arrow with a label at the tip:

>>> fm.annotate_arrow(0.1, 0.5, 0.8, 0.9, label="threshold", label_side="end")

selection_point

selection_point(*, fields: list[str] | None = None, encodings: list[str] | None = None, nearest: bool = False, toggle: str = 'event.shiftKey', on: str = 'click', clear: str = 'mouseout', resolve: Literal['global', 'union', 'intersect'] = 'global', name: str | None = None) -> Selection

Create a point selection activated by clicking on marks.

A point selection highlights individual marks. Shift-click adds to the selection by default (toggle="event.shiftKey"). Use selection_single to disable toggle, or selection_multi to keep the shift-click default explicitly.

Parameters:

Name Type Description Default
fields list of str

Data fields to project the selection onto. When omitted the selection binds to all fields.

None
encodings list of str

Encoding channels to project onto (e.g. ["x", "color"]).

None
nearest bool

When True, clicking between marks selects the nearest one.

False
toggle str

JavaScript event expression controlling when clicking adds to the selection instead of replacing it. Pass "false" to disable toggling (see also selection_single).

"event.shiftKey"
on str

Event that triggers the selection (e.g. "mouseover").

"click"
clear str

Event that clears the selection.

"mouseout"
resolve ('global', 'union', 'intersect')

How to resolve this selection when the chart is faceted.

"global"
name str

Stable identifier for the selection. Auto-generated when omitted.

None

Returns:

Type Description
Selection

Immutable selection descriptor. Pass to Chart.add_selection() and use sel.when(...).otherwise(...) to build conditional encodings.

Examples:

Highlight selected marks by colour:

>>> import ferrum as fm
>>> sel = fm.selection_point()
>>> fm.Chart(df).mark_point().encode(
...     x=fm.X("x"), y=fm.Y("y"),
...     color=sel.when(fm.Color("category")).otherwise(fm.value("#cccccc")),
... ).add_selection(sel)

Nearest-mark selection on mouse-over:

>>> sel = fm.selection_point(nearest=True, on="mouseover", clear="mouseout")

selection_interval

selection_interval(*, fields: list[str] | None = None, encodings: list[str] | None = None, translate: bool = True, zoom: bool = True, mark: SelectionMark | None = None, resolve: Literal['global', 'union', 'intersect'] = 'global', name: str | None = None) -> Selection

Create an interval (brush) selection activated by dragging.

An interval selection lets the user drag a rectangular brush over the chart. All marks inside the brush are considered selected. The brush supports panning (translate=True) and scroll-to-zoom (zoom=True) after it is drawn.

Parameters:

Name Type Description Default
fields list of str

Data fields to project the brush onto. When omitted the brush applies to all fields represented by the brushed encodings.

None
encodings list of str

Encoding channels to constrain the brush to (e.g. ["x"] for a 1-D horizontal brush).

None
translate bool

Allow the user to reposition the brush by dragging inside it.

True
zoom bool

Allow the user to scroll inside the brush to zoom the view.

True
mark SelectionMark

Visual style of the brush rectangle. Defaults to a semi-transparent blue fill with a solid grey border.

None
resolve ('global', 'union', 'intersect')

How to resolve this selection when the chart is faceted.

"global"
name str

Stable identifier for the selection. Auto-generated when omitted.

None

Returns:

Type Description
Selection

Immutable selection descriptor. Pass to Chart.add_selection() and use sel.when(...).otherwise(...) to build conditional encodings.

Examples:

Brush that greys out unselected points:

>>> import ferrum as fm
>>> brush = fm.selection_interval()
>>> fm.Chart(df).mark_point().encode(
...     x=fm.X("x"), y=fm.Y("y"),
...     color=brush.when(fm.Color("category")).otherwise(fm.value("#cccccc")),
... ).add_selection(brush)

Horizontal-only brush:

>>> brush = fm.selection_interval(encodings=["x"])

Custom brush style:

>>> brush = fm.selection_interval(
...     mark=fm.SelectionMark(fill="#4287f5", fill_opacity=0.2, stroke_dash=[4, 2])
... )

value

value(v: Any) -> '_LiteralValue'

Wrap a literal value for use in conditional encodings.

Returns an opaque literal wrapper that can be passed as the if_selected or if_not argument of sel.when(...).otherwise(...) when a constant (rather than a field mapping) is needed.

Parameters:

Name Type Description Default
v str, int, or float

The constant to embed. Hex colour strings (e.g. "#cccccc") are interpreted as colours. Numbers are interpreted as opacity values.

required

Returns:

Type Description
_LiteralValue

Opaque wrapper consumed by ConditionalSpec.

Examples:

Grey-out unselected marks:

>>> import ferrum as fm
>>> sel = fm.selection_point()
>>> fm.Chart(df).mark_point().encode(
...     x=fm.X("x"), y=fm.Y("y"),
...     color=sel.when(fm.Color("category")).otherwise(fm.value("#cccccc")),
... ).add_selection(sel)

Fade unselected marks with low opacity:

>>> color=sel.when(fm.Color("category")).otherwise(fm.value(0.1))

residuals_chart

residuals_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, kind: str = 'studentized', cook_threshold: float | str | None = None, panels: Any = 'auto', annotate_metrics: bool = True, subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Residuals diagnostic chart for a regression estimator.

Plots residuals vs. fitted values. Optional Cook's distance highlighting marks observations whose leverage-adjusted influence exceeds a user-supplied threshold. panels="auto" returns the canonical 4-panel diagnostic layout (residuals-vs-fitted, QQ, scale-location, residuals-vs-leverage) as a 2x2 grid.

Parameters:

Name Type Description Default
model estimator or ModelSource

A fitted sklearn-compatible regression estimator, an explicit ferrum.ModelSource, or a dict of named estimators.

None
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y array - like

Target vector. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y_true array - like

Ground-truth target values for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Predicted target values for the precomputed path.

None
kind ('studentized', 'raw')

Residual type to plot on the y axis. "studentized" uses internally studentized residuals; "raw" uses raw residuals.

"studentized"
cook_threshold float, "auto", or None

Threshold for Cook's distance outlier highlighting. A float is used as an absolute cutoff; "auto" applies the 4 / n rule (Hair et al.); None disables highlighting. Cook's distance is only defined for estimators that expose coef_; non-linear models surface NaN and produce no outliers.

None
panels "auto", None, "single", or list of str

Panel selection. "auto" ships the canonical 4-panel layout -- residuals_vs_fitted, qq, scale_location, and residuals_vs_leverage -- laid out as a 2x2 grid. None or "single" returns just the residuals-vs-fitted panel. Pass an explicit list such as ["residuals_vs_fitted", "qq"] to customize the panel set.

"auto"
annotate_metrics bool

Overlay a top-right corner annotation showing R^2/RMSE/MAE computed from the fit. Pass False to render the residual scatter alone.

True
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource; does not affect deterministic residuals computation.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Residuals-vs-fitted scatter chart with optional Cook's-distance outlier overlay.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import Ridge
>>> fm.residuals_chart(Ridge().fit(X_train, y_train), X_test, y_test)

Precomputed path — residuals are computed as y_true − y_pred internally. Leverage and Cook's distance are unavailable, so the leverage panel is omitted when panels="auto":

>>> fm.residuals_chart(y_true=y_test, y_pred=reg.predict(X_test))

prediction_error_chart

prediction_error_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, reference_line: bool = True, ci: float | None = None, reference_band: bool = False, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Actual-vs-predicted scatter for a regression estimator.

Plots y_true on the y axis against y_pred on the x axis with an optional reference line (y = x diagonal) and an optional residual-based confidence ribbon.

Parameters:

Name Type Description Default
model estimator or ModelSource

A fitted sklearn-compatible regression estimator, an explicit ferrum.ModelSource, or None when pre-computed arrays are supplied via y_true / y_pred.

None
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y array - like

Target vector. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y_true array - like

Pre-computed true labels. Use with y_pred to bypass model inference entirely.

None
y_pred array - like

Pre-computed predictions. Use with y_true to bypass model inference entirely.

None
reference_line bool

Overlay the dashed y = x diagonal.

True
ci float or None

Confidence level in (0, 1). When set, overlays a ribbon spanning the central ci fraction of residuals around the reference line. Raises ValueError if not in (0, 1).

None
reference_band bool

When True (and ci is None), overlays a ±1 RMSE ribbon around the reference line.

False
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Actual-vs-predicted scatter with optional reference line and confidence ribbon.

Examples:

>>> import ferrum as fm
>>> fm.prediction_error_chart(model, X_test, y_test, reference_line=True)

cooks_distance_chart

cooks_distance_chart(model: Any = None, X: Any = None, y: Any = None, *, threshold: float | str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Cook's distance / residuals-vs-leverage diagnostic for a linear estimator.

Renders the residuals-vs-leverage panel with optional Cook's-distance outlier highlighting. Useful for identifying influential observations in a linear regression fit.

Parameters:

Name Type Description Default
model estimator or ModelSource

A fitted sklearn-compatible regression estimator that exposes coef_ (required for leverage-aware Cook's distance), or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y array - like

Target vector. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
threshold float, "auto", or None

Cook's-distance threshold for outlier highlighting. A float is used as an absolute cutoff; "auto" applies the 4 / n rule (Hair et al.); None disables highlighting.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Residuals-vs-leverage panel with optional Cook's-distance outlier overlay.

Examples:

>>> import ferrum as fm
>>> fm.cooks_distance_chart(linear_model, X_test, y_test, threshold="auto")

roc_chart

roc_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, per_class: bool = True, average: str | None = 'macro', annotate_auc: bool = True, subtitle: str | None = None, compare: dict[str, Any] | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

ROC curve chart for a classifier.

Plots true-positive rate vs. false-positive rate, one curve per class (default) or a single macro/micro/weighted-averaged curve. Supports multi-model comparison via compare=.

Parameters:

Name Type Description Default
model estimator, ModelSource, or dict of str -> estimator

Fitted sklearn-compatible classifier, an explicit ferrum.ModelSource, or a dict of named estimators for comparison. When a dict is passed, each estimator is evaluated and curves are overlaid. Mutually exclusive with y_true/y_pred.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
per_class bool

When True, one ROC curve per class is drawn using the one-vs-rest scheme. When False, a single curve averaged per average is drawn.

True
average ('macro', 'micro', 'weighted')

Averaging method used when per_class=False. Ignored when per_class=True.

"macro"
annotate_auc bool

When True, injects one text label per class showing the AUC value to 3 decimal places, anchored in the lower-right corner of the plot.

True
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
compare dict of str -> estimator or None

Additional estimators to overlay. Keys become model labels. model is treated as the base model (label "base").

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

ROC curve chart with one line per class (or averaged curve).

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.roc_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path — bypass the model entirely:

>>> fm.roc_chart(y_true=y_test, y_pred=clf.predict_proba(X_test))

pr_chart

pr_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, per_class: bool = True, average: str | None = 'macro', annotate_ap: bool = True, iso_lines: bool = False, subtitle: str | None = None, compare: dict[str, Any] | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Precision-recall curve chart for a classifier.

Plots precision vs. recall, one curve per class (default) or a single averaged curve. Both axes are pinned to [0, 1.05] so curves render against the full precision-recall space (same convention as sklearn and yellowbrick). Supports multi-model comparison via compare=.

Parameters:

Name Type Description Default
model estimator, ModelSource, or dict of str -> estimator

Fitted sklearn-compatible classifier, an explicit ferrum.ModelSource, or a dict of named estimators for comparison.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
per_class bool

When True, one PR curve per class is drawn using the one-vs-rest scheme. When False, a single curve averaged per average is drawn. Binary classifiers always render a single curve regardless.

True
average ('macro', 'micro', 'weighted')

Averaging method used when per_class=False. Ignored when per_class=True. Macro and weighted variants interpolate per-class precision over a shared recall grid; micro ravels the binarized labels into a single curve.

"macro"
annotate_ap bool

When True, injects one text label per class near the lower- right corner of the plot showing average precision (AP) to 3 decimal places.

True
iso_lines bool

When True, overlays F-score iso-contours at F={0.2, 0.4, 0.6, 0.8} so users can read off combined precision-recall quality directly from the chart.

False
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
compare dict of str -> estimator or None

Additional estimators to overlay. Keys become model labels. model is treated as the base model (label "base").

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Precision-recall curve chart with one line per class (or an averaged summary curve).

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.pr_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path:

>>> fm.pr_chart(y_true=y_test, y_pred=clf.predict_proba(X_test))

calibration_chart

calibration_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, n_bins: int = 10, strategy: str = 'uniform', annotate_brier: bool = True, subtitle: str | None = None, compare: dict[str, Any] | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Calibration (reliability) curve for one or more classifiers.

Plots mean predicted probability vs. fraction of positives in each bin, following sklearn's calibration_curve convention. Supports multi-model comparison via compare=.

Parameters:

Name Type Description Default
model estimator, ModelSource, or dict of str -> estimator

Fitted sklearn-compatible classifier, an explicit ferrum.ModelSource, or a dict of named estimators for comparison. When a dict is passed, each estimator is evaluated and curves are overlaid.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True binary labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
n_bins int

Number of probability bins for the reliability diagram.

10
strategy ('uniform', 'quantile')

Binning strategy forwarded to sklearn.calibration.calibration_curve. "uniform" uses equally-spaced bins; "quantile" uses equal-frequency bins.

"uniform"
annotate_brier bool

When True, attaches the :class:BrierLabel composite (spec 3.11) showing the Brier score per series. The chart title also encodes the Brier value when exactly one model is shown.

True
subtitle str or None

Optional one-line subtitle drawn beneath the chart title.

None
compare dict of str -> estimator or None

Additional estimators to overlay. Keys become model labels. model is treated as the base model (label "base").

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Reliability diagram with one curve per model plus a perfect- calibration diagonal reference.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.calibration_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = 1-D predicted probabilities for positive class):

>>> fm.calibration_chart(y_true=y_test, y_pred=clf.predict_proba(X_test)[:, 1])

gain_chart

gain_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, compare: dict[str, Any] | None = None, subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Cumulative-gain curve for a classifier.

Plots the fraction of positive cases captured vs. the fraction of samples scored, one curve per class. Useful for evaluating the benefit of targeting a top-ranked subset. The categorical legend is replaced with endpoint-anchored direct labels -- unconditional, matching the learning_curve / validation_curve / lift sibling figures (Schwabish C8 audit-rework, 2026-05-12). Use Chart(df).mark_gain(...) directly to keep the legend.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible classifier or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
compare dict[str, estimator] or None

Multi-model overlay. Keys are display names; values are fitted estimators. Routes through _resolve_source -> ComparedModelSource.

None
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Cumulative-gain curve with one line per class.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.gain_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = soft scores, 1-D binary or 2-D multiclass):

>>> fm.gain_chart(y_true=y_test, y_pred=clf.predict_proba(X_test))

lift_chart

lift_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, compare: dict[str, Any] | None = None, subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Lift curve for a classifier.

Plots the ratio of positive-hit rate in the scored top-n vs. random baseline, one curve per class. Values above 1 indicate the model outperforms random selection at that depth. The categorical legend is replaced with endpoint-anchored direct labels -- unconditional (Schwabish C8 audit-rework, 2026-05-12). Use Chart(df).mark_lift(...) directly to keep the legend.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible classifier or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
compare dict[str, estimator] or None

Multi-model overlay. Keys are display names; values are fitted estimators. Routes through _resolve_source -> ComparedModelSource.

None
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Lift curve with one line per class.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.lift_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = soft scores, 1-D binary or 2-D multiclass):

>>> fm.lift_chart(y_true=y_test, y_pred=clf.predict_proba(X_test))

discrimination_threshold_chart

discrimination_threshold_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, n_thresholds: int = 50, metrics: tuple[str, ...] = ('precision', 'recall', 'f1', 'queue_rate'), cv: Any = None, threshold_line: bool = False, optimum_label: bool = True, compare: dict[str, Any] | None = None, subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Discrimination-threshold sweep chart for a binary classifier.

Plots multiple classification metrics (precision, recall, F1, queue rate) as a function of the decision threshold, allowing users to select an operating point that balances competing objectives. The underlying data is unpivoted to long form for multi-metric rendering.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible binary classifier or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True binary labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Soft scores / probabilities for the precomputed path. 1-D for binary classifiers (positive-class scores); 2-D (n_samples, n_classes) for multiclass.

None
n_thresholds int

Number of evenly spaced threshold values in [0, 1] to evaluate.

50
metrics tuple of str

Metric names to plot. Each must be a column in the threshold sweep DataFrame.

("precision", "recall", "f1", "queue_rate")
cv int, cross-validator, or None

When provided, the threshold sweep is computed via cross- validation rather than a single train/test split.

None
threshold_line bool

When True, injects a vertical reference rule at the threshold that maximises F1.

False
optimum_label bool

When True, overlays a text annotation at the F1-optimum point showing the threshold and F1 value (e.g. "max F1 = 0.872 @ t=0.43"). Composes with threshold_line; either can be enabled independently.

True
compare dict[str, estimator] or None

Multi-model overlay. Keys are display names; values are fitted estimators. Routes through _resolve_source -> ComparedModelSource.

None
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Multi-metric line chart over the threshold range.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.discrimination_threshold_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = 1-D positive-class scores; cv= not supported):

>>> fm.discrimination_threshold_chart(y_true=y_test, y_pred=clf.predict_proba(X_test)[:, 1])

confusion_matrix_chart

confusion_matrix_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, normalize: str | None = 'true', annotate: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Confusion matrix heatmap for a classifier.

Renders an ordinal heatmap of (actual class, predicted class) cell values with optional per-cell text annotations. Normalization follows sklearn's confusion_matrix conventions.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible classifier or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Predicted class labels for the precomputed path.

None
normalize ('true', 'pred', 'all')

Normalization scheme for cell values. None shows raw counts; "true" normalizes over actual classes (rows); "pred" normalizes over predicted classes (columns); "all" normalizes over the total number of samples.

"true"
annotate bool

When True, overlays the numeric cell value as a text label in each cell.

True
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Confusion matrix heatmap with optional cell annotations.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.confusion_matrix_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = 1-D hard class labels):

>>> fm.confusion_matrix_chart(y_true=y_test, y_pred=clf.predict(X_test))

class_prediction_error_chart

class_prediction_error_chart(model: Any = None, X: Any = None, y: Any = None, *, y_true: Any = None, y_pred: Any = None, normalize: bool = False, show_counts: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Class prediction-error stacked bar chart for a classifier.

One bar per predicted class, stacked by actual class so misclassified segments are visually distinct. The data source is the unnormalized confusion matrix reshaped to long form.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible classifier or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

True class labels. Required when model is a raw estimator.

None
y_true array - like

Ground-truth class labels for the precomputed path. Must be paired with y_pred; mutually exclusive with model.

None
y_pred array - like

Predicted class labels for the precomputed path.

None
normalize bool

When True, each bar is normalized to 100% (relative composition). When False, bars show raw sample counts.

False
show_counts bool

When True, overlays per-segment count text at the vertical centre of each bar segment (empty segments -- value == 0 -- are skipped). Raw counts are shown regardless of normalize.

True
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Stacked bar chart with one bar per predicted class.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import LogisticRegression
>>> fm.class_prediction_error_chart(LogisticRegression().fit(X_train, y_train), X_test, y_test)

Precomputed path (y_pred = 1-D hard class labels):

>>> fm.class_prediction_error_chart(y_true=y_test, y_pred=clf.predict(X_test))

classification_report_chart

classification_report_chart(model: Any = None, X: Any = None, y: Any = None, *, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Per-class precision / recall / F1 heatmap for a classifier.

Renders a rect-plus-text heatmap where rows are class labels, columns are metrics (precision, recall, f1-score), and cell color encodes the metric value. Each cell is annotated with its value to two decimal places.

Parameters:

Name Type Description Default
model estimator or ModelSource

A fitted sklearn-compatible classifier that exposes predict, or an explicit ferrum.ModelSource.

None
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
y array - like

True labels. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Heatmap with per-class precision / recall / F1-score cells.

Examples:

>>> import ferrum as fm
>>> fm.classification_report_chart(clf, X_test, y_test)

class_balance_chart

class_balance_chart(y: Any, *, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Bar chart of per-class label counts.

Computes the count of each unique class label and renders a vertical bar chart. No model is required — operates on the target array alone.

Parameters:

Name Type Description Default
y array - like

Target label array (1-D). Accepts polars Series, numpy arrays, and any iterable convertible to a flat list.

required
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Vertical bar chart with class labels on x and counts on y.

Examples:

>>> import ferrum as fm
>>> fm.class_balance_chart(y_train)

importance_chart

importance_chart(model: Any, X: Any = None, y: Any = None, *, method: str = 'builtin', top_k: int | None = 20, orient: str = 'horizontal', error_bars: bool = True, show_values: bool = True, subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Feature-importance bar chart for an estimator.

Extracts feature importances from the model via the selected method and renders a ranked bar chart. Error bars are drawn from importance +/- std when available.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource. The estimator must expose feature_importances_ or coef_ for method="builtin".

required
X array - like

Feature matrix. Required when model is a raw estimator. Also required for method="permutation".

None
y array - like

Target vector. Required when model is a raw estimator. Also required for method="permutation".

None
method ('builtin', 'permutation')

Importance extraction method. "builtin" reads feature_importances_ or coef_ directly (std=0). "permutation" runs sklearn.inspection.permutation_importance and populates std for the error bars.

"builtin"
top_k int or None

Maximum number of features to display, ordered by descending absolute importance. Pass None to show all features.

20
orient ('horizontal', 'vertical')

Bar orientation. "horizontal" maps feature names to the y axis; "vertical" maps them to the x axis.

"horizontal"
error_bars bool

When True, draws ±1 std error bars around each bar. Has no visual effect when method="builtin" (std=0).

True
show_values bool

When True, overlays the numeric importance value as a text label on each bar.

True
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource and to permutation_importance when method="permutation".

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Feature-importance bar chart ranked by absolute importance.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import RandomForestClassifier
>>> fm.importance_chart(RandomForestClassifier().fit(X_train, y_train), X_test, y_test)

shap_chart

shap_chart(model: Any, X: Any = None, y: Any = None, *, kind: str = 'beeswarm', max_display: int = 20, sample_idx: int | None = None, order: str = 'abs_mean', background: Any = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

SHAP value chart for an estimator.

Dispatches to one of three chart types based on kind. The beeswarm (default) shows per-sample per-feature SHAP values colored by z-scored feature magnitude. The bar chart aggregates mean absolute SHAP per feature. The waterfall chart shows cumulative contributions for a single sample.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource. SHAP computation requires a tree-based or kernel-explainer-compatible model.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator; not used by the SHAP computation itself.

None
kind ('beeswarm', 'bar', 'waterfall')

Chart type. "beeswarm" renders one point per (sample, feature) colored by z-scored feature value. "bar" renders mean(|shap|) per feature as a horizontal bar. "waterfall" renders cumulative per-feature contributions for the sample at sample_idx.

"beeswarm"
max_display int

Maximum number of features to display, selected by the order ranking criterion.

20
sample_idx int or None

Row index (0-based) of the sample to explain. Required when kind="waterfall"; ignored for other kinds.

None
order ('abs_mean', 'max')

Feature ranking criterion across all three kinds. "abs_mean" ranks by mean absolute SHAP value; "max" by max absolute SHAP value. Drives both the top-max_display selection and the bar/waterfall layout order so all three chart types agree on "most important".

"abs_mean"
background array - like or None

Background dataset for kernel SHAP explainers. When None, the full training set is used. Ignored for tree SHAP.

None
random_state int or None

Seed forwarded to ModelSource; SHAP computation itself is deterministic for tree explainers.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

SHAP beeswarm, bar, or waterfall chart depending on kind.

Raises:

Type Description
ValueError

If kind="waterfall" and sample_idx is not provided.

ValueError

If kind is not one of "beeswarm", "bar", "waterfall".

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> fm.shap_chart(GradientBoostingClassifier().fit(X_train, y_train), X_test, y_test)

shap_beeswarm_chart

shap_beeswarm_chart(model: Any, X: Any = None, y: Any = None, *, max_display: int = 20, order: str = 'abs_mean', background: Any = None, per_class: bool = False, zero_line: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

SHAP beeswarm chart -- per-sample SHAP scatter colored by z-scored value.

per_class=True on a multi-class classifier facets the chart by class. per_class=False (default) renders a single panel using the first class (the only group on regression and binary).

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
max_display int

Maximum number of features to display.

20
order ('abs_mean', 'max')

Feature ranking criterion. "abs_mean" ranks by mean absolute SHAP value; "max" by max absolute SHAP value.

"abs_mean"
background array - like or None

Background dataset for kernel SHAP explainers. Ignored for tree SHAP.

None
per_class bool

Facet by class on multi-class classifiers.

False
zero_line bool

Overlay a dashed vertical reference rule at shap_value = 0 so the sign of each feature's contribution is immediately legible. Automatically skipped on the multi-panel per_class path. Pass False to suppress.

True
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

SHAP beeswarm chart.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> fm.shap_beeswarm_chart(GradientBoostingClassifier().fit(X_train, y_train), X_test, y_test)

shap_bar_chart

shap_bar_chart(model: Any, X: Any = None, y: Any = None, *, max_display: int = 20, order: str = 'abs_mean', background: Any = None, per_class: bool = False, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

SHAP bar chart -- mean absolute SHAP per feature.

per_class=True on a multi-class classifier facets the chart by class. per_class=False (default) renders a single panel using the first class.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
max_display int

Maximum number of features to display.

20
order ('abs_mean', 'max')

Feature ranking criterion. "abs_mean" ranks by mean absolute SHAP value; "max" by max absolute SHAP value.

"abs_mean"
background array - like or None

Background dataset for kernel SHAP explainers. Ignored for tree SHAP.

None
per_class bool

Facet by class on multi-class classifiers.

False
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

SHAP bar chart (features x mean |SHAP|).

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> fm.shap_bar_chart(GradientBoostingClassifier().fit(X_train, y_train), X_test, y_test)

shap_waterfall_chart

shap_waterfall_chart(model: Any, X: Any = None, y: Any = None, *, sample_idx: int, max_display: int = 20, order: str = 'abs_mean', background: Any = None, per_class: bool = False, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

SHAP waterfall chart -- cumulative per-feature contributions for one sample.

per_class=True on a multi-class classifier facets the chart by class (one waterfall panel per class for the same sample). per_class=False (default) renders a single panel using the first class.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
sample_idx int

Row index (0-based) of the sample to explain. Required.

required
max_display int

Maximum number of features to display.

20
order ('abs_mean', 'max')

Feature ranking criterion. "abs_mean" ranks by mean absolute SHAP value; "max" by max absolute SHAP value.

"abs_mean"
background array - like or None

Background dataset for kernel SHAP explainers. Ignored for tree SHAP.

None
per_class bool

Facet by class on multi-class classifiers.

False
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

SHAP waterfall chart for the sample at sample_idx.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> fm.shap_waterfall_chart(
...     GradientBoostingClassifier().fit(X_train, y_train), X_test, y_test,
...     sample_idx=0,
... )

pdp_chart

pdp_chart(model: Any, X: Any = None, y: Any = None, *, features: list | None = None, grid_resolution: int = 100, kind: str = 'average', ice_alpha: float = 0.2, center: bool = False, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Partial-dependence plot (PDP) for one or more features.

Renders one facet panel per feature, each showing how the model prediction changes as that feature varies across its observed range while all other features are held at their column means. Supports average PDP, individual conditional expectation (ICE), and both overlaid.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator; not used by PDP computation.

None
features list of str or int, required

Column names or integer indices of the features to plot. Each feature gets its own facet panel. Must be provided; raises ValueError when None.

None
grid_resolution int

Number of evenly spaced grid points along each feature's range.

100
kind ('average', 'individual', 'both')

"average" renders the mean PDP line. "individual" renders one ICE line per sample. "both" overlays the average curve on top of the ICE lines.

"average"
ice_alpha float

Opacity of individual ICE lines when kind is "individual" or "both".

0.2
center bool

When True, each curve is anchored at zero by subtracting the value at the smallest grid point, making relative changes across features directly comparable.

False
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Faceted PDP chart with one panel per feature.

Raises:

Type Description
ValueError

If features is None.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import GradientBoostingRegressor
>>> fm.pdp_chart(GradientBoostingRegressor().fit(X_train, y_train), X_test, features=["age", "income"])

learning_curve_chart

learning_curve_chart(model: Any, X: Any = None, y: Any = None, *, cv: int = 5, scoring: Any = None, train_sizes: Any = None, ci_style: str = 'band', subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Learning curve chart showing score vs. training set size.

Plots cross-validated train and validation scores as training size grows, revealing overfitting, underfitting, and data-hunger. The CI band is drawn from per-fold score variance.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted (or unfitted) sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
cv int

Number of cross-validation folds.

5
scoring str, callable, or None

Scoring metric forwarded to sklearn.model_selection.learning_curve. When None, the estimator's default scorer is used.

None
train_sizes array - like or None

Relative or absolute training sizes to evaluate. When None, sklearn's default np.linspace(0.1, 1.0, 5) is used.

None
ci_style ('band', 'errorbar')

Visual style of the confidence interval. "band" draws a shaded ribbon; "errorbar" draws error bars.

"band"
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Learning curve with train and validation score lines plus CI.

Examples:

>>> import ferrum as fm
>>> from sklearn.svm import SVC
>>> fm.learning_curve_chart(SVC(), X_train, y_train, cv=5)

validation_curve_chart

validation_curve_chart(model: Any, X: Any = None, y: Any = None, *, param: str = 'alpha', values: Any = None, cv: int = 5, scoring: Any = None, log_scale: Any = 'auto', ci_style: str = 'band', subtitle: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Plot score vs. a single hyperparameter value.

Sweeps one hyperparameter over a supplied value range and plots cross-validated train and validation scores, revealing the bias- variance tradeoff for that parameter. The x axis is log-scaled automatically when the value range spans more than two orders of magnitude.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted (or unfitted) sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
param str

Name of the hyperparameter to sweep, passed to sklearn.model_selection.validation_curve as param_name.

"alpha"
values (array - like, required)

Values of param to evaluate. Must be provided; raises ValueError when None.

None
cv int

Number of cross-validation folds.

5
scoring str, callable, or None

Scoring metric. When None, the estimator's default scorer is used.

None
log_scale bool or 'auto'

Whether to use a log scale on the x axis. "auto" enables log scale when max(values) / min(non-zero values) > 100.

"auto"
ci_style ('band', 'errorbar')

Visual style of the confidence interval.

"band"
subtitle str or None

Optional subtitle rendered beneath the active chart title.

None
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Validation curve with train and validation score lines plus CI.

Raises:

Type Description
ValueError

If values is None.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import Ridge
>>> fm.validation_curve_chart(Ridge(), X_train, y_train, param="alpha", values=[0.01, 0.1, 1, 10])

cv_scores_chart

cv_scores_chart(model: Any, X: Any = None, y: Any = None, *, cv: int = 5, scoring: Any = None, kind: str = 'box', split: str = 'both', random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Per-fold cross-validation score distribution chart.

Visualizes the distribution of scores across folds for train and/or validation splits, making variance and consistency across folds immediately visible.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted (or unfitted) sklearn-compatible estimator or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
cv int

Number of cross-validation folds.

5
scoring str, callable, or None

Scoring metric. When None, the estimator's default scorer is used.

None
kind ('box', 'strip', 'bar')

Chart type. "box" renders a box-and-whisker per split; "strip" renders individual fold points; "bar" renders the mean score per split as a bar (pre-aggregated).

"box"
split ('both', 'train', 'test')

Which CV split to show. "both" shows train and validation side by side; "train" or "test" restricts to one split.

"both"
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

Per-fold CV score distribution chart.

Examples:

>>> import ferrum as fm
>>> from sklearn.ensemble import RandomForestClassifier
>>> fm.cv_scores_chart(RandomForestClassifier(), X_train, y_train, cv=10)

alpha_selection_chart

alpha_selection_chart(model: Any, X: Any = None, y: Any = None, *, alphas: Any = None, cv: int = 5, scoring: Any = None, log_scale: bool = True, highlight_best: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Regularization-strength (alpha) selection chart.

Plots cross-validated mean score as a function of regularization strength, helping users identify the optimal alpha for penalized estimators such as Ridge, Lasso, and ElasticNet.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted (or unfitted) sklearn-compatible penalized estimator or an explicit ferrum.ModelSource. The estimator must accept an alpha constructor parameter.

required
X array - like

Feature matrix. Required when model is a raw estimator.

None
y array - like

Target vector. Required when model is a raw estimator.

None
alphas (array - like, required)

Regularization-strength values to sweep. Must be provided; raises ValueError when None.

None
cv int

Number of cross-validation folds.

5
scoring str, callable, or None

Scoring metric. When None, the estimator's default scorer is used.

None
log_scale bool

When True, the alpha axis is log-scaled.

True
highlight_best bool

When True, injects a vertical reference rule at the alpha that maximises mean CV score.

True
random_state int or None

Seed forwarded to ModelSource.

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None

Returns:

Type Description
Chart

CV-score-vs-alpha line chart with optional best-alpha rule.

Raises:

Type Description
ValueError

If alphas is None.

Examples:

>>> import ferrum as fm
>>> from sklearn.linear_model import Ridge
>>> fm.alpha_selection_chart(Ridge(), X_train, y_train, alphas=[0.001, 0.01, 0.1, 1, 10, 100])

pca_scree_chart

pca_scree_chart(model: Any, X: Any = None, *, n_components: int | None = None, cumulative_line: bool = True, threshold: float | None = 0.95, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

PCA scree chart showing explained variance per component.

Plots per-component explained variance ratio as bars, with an optional cumulative-variance overlay line and a horizontal reference rule at a target cumulative-variance threshold.

Parameters:

Name Type Description Default
model PCA estimator, ModelSource, or DataFrame

A fitted sklearn.decomposition.PCA instance, an explicit ferrum.ModelSource wrapping one, an unfitted PCA estimator (fit is run on X), or a raw polars/pandas DataFrame (variance computed via Rust SVD -- no sklearn needed).

required
X array - like

Feature matrix. Required when model is a raw (unfitted) estimator; ignored when it is already a ModelSource with data bound.

None
n_components int or None

Number of components to display. When None, all available components from the fitted PCA are shown.

None
cumulative_line bool

When True, overlays a cumulative explained-variance line.

True
threshold float or None

When a float is given, draws a horizontal reference rule at that cumulative-variance level (e.g. 0.95 marks where 95% of variance is explained). Pass None to omit the rule.

0.95
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

PCA scree bar chart with optional cumulative line and threshold rule.

Examples:

>>> import ferrum as fm
>>> from sklearn.decomposition import PCA
>>> fm.pca_scree_chart(PCA(n_components=10).fit(X_train), threshold=0.90)

Raw DataFrame (no sklearn required):

>>> fm.pca_scree_chart(X_train, n_components=10)

cluster_diagnostics

cluster_diagnostics(X: Any, *, ks: Any, method: str = 'kmeans', scoring: str = 'both', n_init: int = 10, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart | HConcatChart'

Elbow and silhouette diagnostics over a range of cluster counts.

Fits one clusterer per value of k and renders the requested diagnostic panel(s): distortion (inertia) vs. k, mean silhouette score vs. k, or both side-by-side. Unlike the other figure functions, this sweeps the model class itself rather than wrapping a single pre-fitted ModelSource.

Parameters:

Name Type Description Default
X array - like

Feature matrix. All samples are used for fitting and scoring. Polars DataFrames, pandas DataFrames, and 2D numpy arrays are accepted.

required
ks iterable of int

Values of k (number of clusters) to evaluate.

required
method ('kmeans', 'hierarchical')

Clustering algorithm.

  • "kmeans" -- sklearn.cluster.KMeans. Uses the estimator's native inertia_ attribute.
  • "hierarchical" -- sklearn.cluster.AgglomerativeClustering (Ward linkage). Inertia is computed manually as the sum of squared distances from each sample to its cluster centroid, since AgglomerativeClustering does not expose inertia_.

DBSCAN is intentionally not supported -- its number of clusters is determined by eps / min_samples, not by a swept k, so the chart's elbow / silhouette-vs-k axis doesn't apply.

"kmeans"
scoring ('elbow', 'silhouette', 'both')

Which diagnostic panel(s) to render.

  • "elbow" -- inertia-vs-k line chart only.
  • "silhouette" -- mean silhouette-vs-k line chart only.
  • "both" -- side-by-side HConcatChart of the two.
"elbow"
n_init int

Number of KMeans initializations per k; forwarded to sklearn.cluster.KMeans(n_init=...). Ignored for hierarchical clustering, which is deterministic given the linkage strategy.

10
random_state int or None

Random seed for KMeans initialisation. When None, defaults to seed 0 for deterministic results. Ignored for hierarchical clustering.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart or HConcatChart

Chart when scoring is "elbow" or "silhouette"; HConcatChart with both panels side-by-side when scoring="both".

Raises:

Type Description
ValueError

If method is unknown or scoring is not in the supported set.

Examples:

>>> import ferrum as fm
>>> fm.cluster_diagnostics(X_train, ks=range(2, 11))
>>> fm.cluster_diagnostics(X_train, ks=range(2, 11),
...                         method="hierarchical", scoring="silhouette")

intercluster_distance_chart

intercluster_distance_chart(model: Any, X: Any = None, *, k: int | None = None, method: str = 'mds', random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Intercluster distance map: 2D embedding of cluster centers.

Embeds cluster centers into 2D using MDS so their pairwise distances are approximately preserved. Each center is rendered as a size-encoded circle (bubble area proportional to cluster count). A 15% padding is added around the data range so large bubbles do not clip at axis edges.

Parameters:

Name Type Description Default
model fitted clusterer or ModelSource

A fitted sklearn-compatible clusterer (must expose cluster_centers_ or n_clusters) or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix used to compute cluster member counts. Required when model is a raw estimator.

None
k int or None

Number of clusters. When None, inferred from model.n_clusters or len(model.cluster_centers_); raises ValueError if neither attribute is present.

None
method ('mds', 'tsne')

Dimensionality-reduction method for embedding cluster centers. "mds" (default) uses sklearn MDS to preserve pairwise distances; "tsne" uses t-SNE (perplexity clamped to min(5, k-1) for small cluster counts).

"mds"
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

2D scatter chart of embedded cluster centers sized by cluster population.

Raises:

Type Description
ValueError

If k is None and the model exposes neither n_clusters nor cluster_centers_.

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> fm.intercluster_distance_chart(KMeans(n_clusters=5).fit(X_train), X_train)

silhouette_chart

silhouette_chart(model: Any, X: Any = None, *, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Rousseeuw silhouette plot for a fitted clusterer.

Computes per-sample silhouette coefficients and renders a horizontal bar chart sorted by cluster, one bar per sample, colored by cluster label.

Parameters:

Name Type Description Default
model fitted clusterer or ModelSource

A fitted sklearn-compatible clustering estimator that exposes labels_, or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Horizontal silhouette bar chart with per-cluster color encoding.

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> fm.silhouette_chart(KMeans(n_clusters=3, random_state=0).fit(X), X)

manifold_chart

manifold_chart(model: Any, X: Any = None, *, method: str = 'umap', random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Low-dimensional manifold-embedding scatter (UMAP / t-SNE / PCA).

Projects the input data to two dimensions via the selected embedding algorithm and renders a point chart with axes dim_0 / dim_1 colored by cluster label.

Parameters:

Name Type Description Default
model fitted clusterer or ModelSource

A fitted clustering estimator whose labels_ attribute colors the points, or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Required when model is a raw estimator; ignored when it is already a ModelSource.

None
method str

Embedding algorithm. Typical values are "umap", "tsne", and "pca".

"umap"
random_state int or None

Seed forwarded to ModelSource for stochastic embeddings.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

2-D scatter plot of the embedded data, colored by cluster label.

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> fm.manifold_chart(KMeans(n_clusters=4, random_state=0).fit(X), X, method="tsne")

elbow_chart

elbow_chart(model: Any, X: Any, *, ks: Any, metric: str = 'distortion', random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Elbow / score sweep over a range of k for a clustering algorithm.

Fits one model per k value and plots the selected score metric against k. Useful for identifying the optimal number of clusters visually.

Parameters:

Name Type Description Default
model type

Uninstantiated clustering class (e.g. sklearn.cluster.KMeans). Must accept n_clusters, random_state, and n_init keyword arguments.

required
X array - like

Feature matrix used to fit each per-k model.

required
ks sequence of int

The candidate k values to sweep (e.g. range(2, 11)).

required
metric ('distortion', 'silhouette', 'calinski_harabasz')

Score to optimize. "distortion" is minimized; "silhouette" and "calinski_harabasz" are maximized.

"distortion"
random_state int or None

Seed passed to every per-k model instantiation.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Score-vs-k line chart with the optimal k annotated.

Examples:

>>> import ferrum as fm
>>> from sklearn.cluster import KMeans
>>> fm.elbow_chart(KMeans, X_train, ks=range(2, 9))

decision_boundary_chart

decision_boundary_chart(model: Any, X: Any, y: Any = None, *, features: tuple = (0, 1), grid_resolution: int = 200, proba: bool = False, scatter: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Decision-boundary heatmap for a classifier over a 2D feature slice.

Builds a grid_resolution x grid_resolution grid over two selected features, holds all other features fixed at their column means, and colors each cell by the model's predicted class (or probability). Optionally overlays training-point scatter.

Parameters:

Name Type Description Default
model estimator or ModelSource

Fitted sklearn-compatible classifier or an explicit ferrum.ModelSource.

required
X array - like

Feature matrix. Must be provided (not optional) so the grid bounds and column means can be computed.

required
y array - like or None

True labels. Used only for the scatter overlay when scatter=True; not required otherwise.

None
features tuple of (int or str, int or str)

Two feature indices or column names to use for the x and y axes of the grid. All other features are fixed at their column means. Exactly 2 features are required.

(0, 1)
grid_resolution int

Number of grid points along each axis; total cells = grid_resolution**2.

200
proba bool

When True and the model exposes predict_proba, the color channel uses predict_proba[:, 1] (continuous probability). When False, the color channel uses predict (discrete class index).

False
scatter bool

When True, overlays a scatter of training points colored by y on top of the boundary heatmap via the + compositor. Note: the overlay currently renders as horizontal concatenation per the ChartSpec one-batch contract.

False
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Decision-boundary heatmap, optionally with training-point scatter overlay.

Raises:

Type Description
ValueError

If features does not contain exactly 2 elements.

Examples:

>>> import ferrum as fm
>>> from sklearn.svm import SVC
>>> fm.decision_boundary_chart(SVC().fit(X_train, y_train), X_train, y_train, features=(0, 1))

rank_chart

rank_chart(source: Any, X: Any = None, y: Any = None, *, rank: str = '2d', algorithm: str | None = None, top_k: int | None = None, annot: bool = True, orient: str = 'horizontal', color_field: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Feature-ranking chart: univariate bar or pairwise heatmap.

Computes a ranking score for each feature (or each feature pair) and renders either a ranked bar chart (rank="1d") or a pairwise correlation heatmap (rank="2d"). Accepts a fitted estimator, ModelSource, or a raw DataFrame / 2D array (no model required for most algorithms).

Parameters:

Name Type Description Default
source estimator, ModelSource, DataFrame, or array-like

Input data. When a fitted estimator or ModelSource is supplied, the feature matrix is taken from the bound data. When a DataFrame or 2D array is supplied, X is used as the feature matrix if provided.

required
X array - like

Feature matrix. Used when source is a raw estimator (not a ModelSource) or when source is a raw DataFrame and X overrides it.

None
y array - like

Target vector. Required only for algorithm="covariance" which routes through ModelSource.rank1d.

None
rank ('1d', '2d')

Ranking mode. "1d" computes a univariate score per feature and renders a horizontal bar chart (or vertical with orient="vertical"). "2d" computes pairwise scores and renders a heatmap.

"1d"
algorithm str or None

Ranking algorithm. When None, defaults to "shapiro" for rank="1d" and "pearson" for rank="2d".

None
top_k int or None

For rank="1d", truncate to the top-k features by score. Has no effect for rank="2d".

None
annot bool

For rank="2d", overlays the correlation value (2 decimal places) as a text label in each heatmap cell. Has no effect for rank="1d".

True
orient ('horizontal', 'vertical')

Bar orientation for rank="1d"; ignored for rank="2d".

"horizontal"
color_field str or None

Column name to use for bar fill color in rank="1d"; when None, a single color is used.

None
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Ranked bar chart (rank="1d") or pairwise heatmap (rank="2d").

Raises:

Type Description
ValueError

If rank is not "1d" or "2d".

Examples:

>>> import ferrum as fm
>>> fm.rank_chart(X_train, rank="2d")
>>> fm.rank_chart(X_train, rank="1d", algorithm="shapiro", top_k=10)

.. deprecated:: 2026-05-12 Use :func:rank1d_chart or :func:rank2d_chart directly. This dispatcher remains as a shim that forwards to the appropriate sibling and will be removed in a future major release.

rank1d_chart

rank1d_chart(source: Any, X: Any = None, y: Any = None, *, algorithm: str | None = None, top_k: int | None = None, orient: str = 'horizontal', color_field: str | None = None, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Univariate feature-ranking bar chart.

Computes a per-feature ranking score and renders a horizontal (or vertical with orient="vertical") bar chart sorted by score. Accepts a fitted estimator, ModelSource, or a raw DataFrame / 2D array; the "covariance" algorithm requires y.

Parameters:

Name Type Description Default
source estimator, ModelSource, DataFrame, or array-like

Input data. When a fitted estimator or ModelSource is supplied, the feature matrix is taken from the bound data.

required
X optional

Feature matrix / target -- forwarded to _resolve_source when source is a raw estimator.

None
y optional

Feature matrix / target -- forwarded to _resolve_source when source is a raw estimator.

None
algorithm str or None

Ranking algorithm. None selects "shapiro".

None
top_k int or None

Limit the chart to the top-k features by score. None shows all features.

None
orient ('horizontal', 'vertical')

Bar orientation.

"horizontal"
color_field str or None

Column name to map to bar color.

None
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Ranked bar chart.

Examples:

>>> import ferrum as fm
>>> fm.rank1d_chart(model, X_train, algorithm="shapiro")

rank2d_chart

rank2d_chart(source: Any, X: Any = None, y: Any = None, *, algorithm: str | None = None, annot: bool = True, random_state: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Pairwise feature-correlation heatmap.

Computes pairwise feature correlation (or covariance) and renders a heatmap. Accepts a fitted estimator, ModelSource, or a raw DataFrame / 2D array (no model required).

Parameters:

Name Type Description Default
source estimator, ModelSource, DataFrame, or array-like

Input data.

required
X optional

Feature matrix / target.

None
y optional

Feature matrix / target.

None
algorithm str or None

Ranking algorithm. None selects "pearson".

None
annot bool

Overlay the correlation value (2 decimals) on each cell.

True
random_state int or None

Seed forwarded to ModelSource.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Pairwise correlation heatmap.

Examples:

>>> import ferrum as fm
>>> fm.rank2d_chart(model, X_train, algorithm="pearson")

parallel_coordinates_chart

parallel_coordinates_chart(data: Any, *, features: list[str] | None = None, hue: str | None = None, rescale: str | None = 'minmax', alpha: float = 0.5, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None) -> 'Chart'

Parallel coordinates chart for multivariate data.

Renders one polyline per sample, with each feature mapped to a vertical axis. Features are optionally rescaled to a common range before plotting so all axes are visually comparable. Samples are colored by a grouping column when hue is provided.

Parameters:

Name Type Description Default
data polars.DataFrame, pandas.DataFrame, or array-like

Input data. Polars and pandas DataFrames are used directly; 2D numpy arrays are auto-named f0, f1, etc.

required
features list of str or None

Column names to use as parallel axes. When None, all columns except hue are used.

None
hue str or None

Column name to color samples by (e.g. a target class or cluster id). Pass None for monochrome lines.

None
rescale ('minmax', 'zscore')

Per-feature rescaling applied before rendering so axes share a common visual range. "minmax" maps to [0, 1]; "zscore" standardizes to zero mean and unit variance; None uses raw feature values.

"minmax"
alpha float

Opacity of individual polylines; lower values reduce overplot in dense datasets.

0.5
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
theme Theme or None

Ferrum theme to apply to the returned chart.

None

Returns:

Type Description
Chart

Parallel coordinates chart with one polyline per sample.

Raises:

Type Description
ValueError

If any name in features is not a column in data.

ValueError

If rescale is not one of "minmax", "zscore", or None.

Examples:

>>> import ferrum as fm
>>> fm.parallel_coordinates_chart(X_df, hue="species", rescale="minmax")

displot

displot(data: Any, *, x: Any = None, y: Any = None, hue: Any = None, col: Any = None, row: Any = None, kind: str = 'hist', fill: bool = True, cumulative: bool = False, log_scale: bool = False, stat: str = 'count', bins: Any = 'sturges', bandwidth: Any = 'scott', bw_adjust: float = 1.0, multiple: str = 'layer', kde: bool = False, rug: bool = False, height: float | None = None, aspect: float | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Univariate distribution plot.

Convenience wrapper that dispatches to mark_histogram, mark_density, or mark_tick based on kind. The multiple parameter controls how overlapping groups (from hue) are positioned, and the kde / rug flags optionally layer additional marks on top of the primary kind.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str or encoding

Column name for the distribution variable (horizontal axis).

None
y str or encoding

Column name for the distribution variable (vertical axis).

None
hue str or encoding

Column name to map to color (one distribution per level).

None
col str

Column name for faceting across columns.

None
row str

Column name for faceting across rows.

None
kind ('hist', 'kde', 'ecdf', 'rug')

Which distribution mark to draw. "hist" calls mark_histogram; "kde" calls mark_density (filled by default); "ecdf" builds a cumulative frequency line via Bin + mark_line; "rug" calls mark_tick.

"hist"
fill bool

Fill the area under the KDE curve (kind="kde" only).

True
cumulative bool

Produce a cumulative histogram or density (kind="hist" and kind="kde").

False
log_scale bool

Apply a log scale to the x axis.

False
stat ('count', 'density')

Statistic to plot on the value axis for kind="hist". "density" normalises so the total area integrates to 1.

"count"
bins int or str

Binning rule for kind="hist". An integer is forwarded as bin_count; a string ("sturges", "fd", etc.) lets the Rust engine decide the count automatically.

"sturges"
bandwidth str

Bandwidth selector for kind="kde" ("scott" or "silverman").

"scott"
bw_adjust float

Multiplicative bandwidth adjustment for kind="kde".

1.0
multiple ('layer', 'stack', 'fill', 'dodge')

How to render multiple distributions (one per hue level). "layer" overlays them (Identity); "dodge" places them side by side; "stack" and "fill" use Stack with offset="zero" or offset="normalize" respectively.

"layer"
kde bool

When True and kind != "kde", layer a mark_density on top of the primary mark.

False
rug bool

When True and kind != "rug", layer a mark_tick rug on top of the primary mark.

False
height float or None

Height of the chart in pixels. Width is derived from aspect.

None
aspect float or None

Aspect ratio (width = height * aspect). Requires height.

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Configured chart (possibly layered, faceted, or sized).

Raises:

Type Description
ValueError

If kind or multiple is not one of the supported values.

ValueError

If kind="ecdf" is used without specifying x=.

Examples:

>>> import ferrum as fm
>>> fm.displot(df, x="sepal_length")

KDE with per-species coloring:

>>> fm.displot(df, x="sepal_length", hue="species", kind="kde")

Stacked histogram with an overlaid rug:

>>> fm.displot(df, x="tip", hue="sex", multiple="stack", rug=True)

catplot

catplot(data: Any, *, x: Any = None, y: Any = None, hue: Any = None, col: Any = None, row: Any = None, kind: str = 'strip', order: Any = None, hue_order: Any = None, orient: Any = None, dodge: bool = False, jitter: bool = True, native_scale: bool = False, ci: Any = 95, n_boot: int = 1000, seed: int | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Categorical figure-level function.

Dispatches to the appropriate mark based on kind:

  • "strip" -- mark_point with Jitter (when jitter=True, default) or Dodge (when dodge=True and hue is set).
  • "swarm" -- mark_swarm.
  • "box" -- mark_boxplot (box + whiskers + outliers).
  • "violin" -- mark_violin (kernel-density outline).
  • "boxen" -- mark_boxen (letter-value / extended box).
  • "point" -- mark_point per observation on the categorical axis.
  • "bar" -- mark_bar per observation on the categorical axis.
  • "count" -- Aggregate(count) + mark_bar.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str or encoding

Column name for the horizontal axis (categorical by default).

None
y str or encoding

Column name for the vertical axis (value by default).

None
hue str or encoding

Column name to map to color (one visual group per level).

None
col str

Column name for faceting across columns.

None
row str

Column name for faceting across rows.

None
kind ('strip', 'swarm', 'box', 'violin', 'boxen', 'point', 'bar', 'count')

Which categorical mark to draw.

"strip"
order list of str

Explicit ordering for the categorical axis levels. Passed as sort=order on the categorical-axis encoding so the domain renders in the given order.

None
hue_order list of str

Explicit ordering for hue levels. Passed as sort=hue_order on the color encoding.

None
orient ('h', 'v', None)

"h" flips the axes (x becomes the value axis, y the category axis) and applies CoordFlip. "v" and None are both treated as vertical (the default); no error is raised for other values.

"h"
dodge bool

When True and hue is set, apply Dodge so each hue level is drawn side-by-side rather than overlaid.

False
jitter bool

For kind="strip", add Jitter on the categorical axis. Ignored when dodge=True.

True
native_scale bool

When True, treat the categorical axis as quantitative instead of ordinal (preserves numeric spacing rather than equal-spacing categories). Currently raises ValueError because the renderer does not support quantitative categorical axes.

False
ci int or float

Confidence-interval level (0--100) for "point" and "bar" kinds. Currently raises ValueError because the Summary transform is not yet wired into catplot.

95
n_boot int

Bootstrap iteration count used to compute ci. Currently raises ValueError alongside ci.

1000
seed int or None

Random seed forwarded to Jitter for reproducible strip positions.

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Configured chart (possibly faceted or coord-flipped).

Raises:

Type Description
ValueError

If kind is not one of the supported values.

ValueError

If kind="count" is used without specifying x (or y when orient="h").

ValueError

If native_scale=True is passed (not yet supported by the renderer).

ValueError

If ci is not the default value 95 and the kind is "point" or "bar" (Summary transform not yet wired).

Examples:

>>> import ferrum as fm
>>> fm.catplot(df, x="species", y="sepal_length", kind="box")

Group by a hue variable with dodged bars:

>>> fm.catplot(df, x="day", y="tip", hue="sex", kind="bar", dodge=True)

Horizontal violin plot:

>>> fm.catplot(df, x="total_bill", y="day", kind="violin", orient="h")

relplot

relplot(data: Any, *, x: Any, y: Any, hue: Any = None, size: Any = None, style: Any = None, col: Any = None, row: Any = None, kind: str = 'scatter', height: float | None = None, aspect: float | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Relational figure-level function for scatter and line plots.

Dispatches to the appropriate mark based on kind:

  • "scatter" -- mark_point(). style maps to Shape.
  • "line" -- mark_line(). style maps to StrokeDash.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str or encoding

Column name for the horizontal axis (required).

required
y str or encoding

Column name for the vertical axis (required).

required
hue str or encoding

Column name to map to color (one group per level).

None
size str or encoding

Column name to map to the Size channel (point area or line width).

None
style str or encoding

Column name to map to Shape (scatter) or StrokeDash (line).

None
col str

Column name for faceting across columns.

None
row str

Column name for faceting across rows.

None
kind ('scatter', 'line')

Which relational mark to draw.

"scatter"
height float or None

Height of the chart in pixels. Width is derived from aspect.

None
aspect float or None

Aspect ratio (width = height * aspect). Requires height.

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Configured chart (possibly faceted or sized).

Raises:

Type Description
ValueError

If kind is not one of "scatter" or "line".

Examples:

Scatter with hue grouping and column faceting:

>>> import ferrum as fm
>>> fm.relplot(df, x="total_bill", y="tip", hue="sex", col="time")

Line plot with per-level dash styling:

>>> fm.relplot(df, x="timepoint", y="signal", hue="region",
...            style="region", kind="line")

lmplot

lmplot(data: Any, *, x: str, y: str, hue: Any = None, col: Any = None, row: Any = None, method: str = 'lm', ci: Any = 95, order: int = 1, scatter: bool = True, scatter_kws: Any = None, line_kws: Any = None, truncate: bool = True, x_bins: Any = None, x_estimator: Any = None, x_jitter: Any = None, logx: bool = False, show_metrics: bool = True, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Linear (and non-linear) regression scatter overlay.

Builds a layered chart with an optional scatter (mark_point) and a regression fit line, dispatching to the appropriate transform:

  • "lm" -- mark_smooth(method="lm") (polynomial degree controlled by order).
  • "loess" -- mark_smooth(method="loess").
  • "logistic" -- Logistic transform + mark_line.
  • "glm" -- Glm transform + mark_line.
  • "robust" -- Robust transform + mark_line.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str

Column name for the horizontal (predictor) axis (required).

required
y str

Column name for the vertical (response) axis (required).

required
hue str or encoding

Column name to map to color; fit lines are drawn per hue level.

None
col str

Column name for faceting across columns.

None
row str

Column name for faceting across rows.

None
method ('lm', 'logistic', 'glm', 'loess', 'robust')

Fitting method.

"lm"
ci int or None

Confidence interval level (0--100) shown as a band around the fit line. Pass None to suppress.

95
order int

Polynomial degree forwarded to mark_smooth when method="lm".

1
scatter bool

Include a scatter layer (mark_point). Set to False to show only the fit line.

True
scatter_kws dict

Extra keyword arguments forwarded to the scatter mark_point call (e.g. {"opacity": 0.3, "size": 20}).

None
line_kws dict

Extra keyword arguments forwarded to the regression-line mark call (e.g. {"stroke_width": 3}).

None
truncate bool

When True (default), the fit line spans only the observed data range (min to max of x). When False, raises ValueError because extending the fit line beyond the data range requires Rust-side x_range support (tracked in the design spec WI-7).

True
x_bins any

Forwarded as x_bins to mark_smooth for binning the x-axis before fitting (method="lm" only).

None
x_estimator any

Forwarded as x_estimator to mark_smooth (method="lm" only).

None
x_jitter float or None

When set, applies Jitter(axis="x", width=x_jitter) to the scatter layer.

None
logx bool

Apply a log scale to the x-axis on both scatter and fit layers.

False
show_metrics bool

Schwabish SB-followup (2026-05-12): overlay a top-right corner annotation with R^2 / RMSE / MAE computed from the OLS fit (method="lm", no hue). Silently skipped for non-LM methods (loess, robust, logistic, glm -- different metric space) or when hue is set (per-group corners would crowd).

True
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Layered chart (scatter + fit) or fit-only when scatter=False. May be faceted.

Raises:

Type Description
ValueError

If method is not one of the supported values.

ValueError

If truncate=False (extending the fit line beyond the data range is not yet supported).

Examples:

>>> import ferrum as fm
>>> fm.lmplot(df, x="total_bill", y="tip")

Logistic regression with per-sex fit lines:

>>> fm.lmplot(df, x="total_bill", y="smoker_int", method="logistic", hue="sex")

Polynomial fit (degree 2) with no confidence band:

>>> fm.lmplot(df, x="size", y="tip", order=2, ci=None)

residplot

residplot(data: Any, *, x: str, y: str, lowess: bool = False, order: int = 1, robust: bool = False, dropna: bool = True, show_metrics: bool = True, zero_line: bool = True, label: Any = None, color: Any = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Residual-diagnostic scatter plot.

Computes regression residuals via Smooth(output="residuals") (or Robust(output="residuals") when robust=True) and plots (x, residual) with mark_point. When lowess=True, a mark_line lowess smoother is layered over the residuals to help diagnose non-linearity.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str

Column name for the horizontal axis (predictor; required).

required
y str

Column name used to compute residuals (response; required).

required
lowess bool

Overlay a lowess smoother on the residuals using Smooth(method="loess").

False
order int

Polynomial degree of the regression used to compute residuals.

1
robust bool

Use Robust regression (MM-estimator) instead of OLS when computing residuals. Compatible with show_metrics=True and zero_line=True (annotations flow through the Robust transform's same opt-in kwargs).

False
dropna bool

Drop rows where x or y is null before fitting.

True
show_metrics bool

Schwabish SB-followup (2026-05-12): overlay a top-right corner annotation with R^2 / RMSE / MAE computed inside the Rust Smooth/Robust transform via the inject_metrics=True kwarg -- same single execution model as fitted residuals, no Python-side regression duplication.

True
zero_line bool

Schwabish SB-followup: draw a dashed horizontal reference at y=0 via the Rust transform's inject_zero_ref=True opt-in.

True
label str

Legend label for the residual series. When set, a constant _label column is injected and mapped to color, producing a single-entry legend.

None
color str or encoding

Column name or constant color forwarded to Chart.encode(color=).

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Scatter of residuals (possibly with a lowess layer, zero reference line, and corner R^2/RMSE/MAE annotation).

Examples:

>>> import ferrum as fm
>>> fm.residplot(df, x="total_bill", y="tip")

Robust residuals with annotations:

>>> fm.residplot(df, x="size", y="tip", robust=True)

regplot

regplot(data: Any, *, x: str, y: str, hue: Any = None, method: str = 'lm', ci: Any = 95, order: int = 1, scatter: bool = True, scatter_kws: Any = None, line_kws: Any = None, truncate: bool = True, x_jitter: Any = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

Axes-level regression scatter plot.

The axes-level equivalent of lmplot — identical API except col= and row= are excluded because regplot does not facet. Every parameter is forwarded to lmplot unchanged.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str

Column name for the horizontal (predictor) axis (required).

required
y str

Column name for the vertical (response) axis (required).

required
hue str or encoding

Column name to map to color; fit lines are drawn per hue level.

None
method ('lm', 'logistic', 'glm', 'loess', 'robust')

Fitting method forwarded to lmplot.

"lm"
ci int or None

Confidence interval level (0--100) shown as a band around the fit line. Pass None to suppress.

95
order int

Polynomial degree forwarded to mark_smooth when method="lm".

1
scatter bool

Include a scatter layer (mark_point).

True
scatter_kws dict

Extra keyword arguments forwarded to the scatter mark_point call.

None
line_kws dict

Extra keyword arguments forwarded to the regression-line mark call.

None
truncate bool

When True, the fit line spans only the observed data range.

True
x_jitter float or None

When set, applies Jitter(axis="x", width=x_jitter) to the scatter layer.

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Layered chart (scatter + fit) or fit-only when scatter=False.

Raises:

Type Description
ValueError

If method is not one of the supported values.

ValueError

If truncate=False (extending the fit line beyond the data range is not yet supported).

Examples:

>>> import ferrum as fm
>>> fm.regplot(df, x="total_bill", y="tip")

Robust regression:

>>> fm.regplot(df, x="size", y="tip", method="robust")

pairplot

pairplot(data: Any, *, vars: Any = None, x_vars: Any = None, y_vars: Any = None, hue: Any = None, kind: str = 'scatter', diag_kind: str = 'auto', markers: Any = None, height: float | None = None, aspect: float | None = None, corner: bool = False, dropna: bool = False, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> RepeatChart

Pairwise-scatter grid (scatterplot matrix).

Returns a RepeatChart whose template repeats over the cartesian product of row x column field lists, resolved from vars or x_vars/y_vars. When neither is supplied, all numeric columns in data are used.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
vars sequence of str

Column names to plot on both axes (symmetric grid). Cannot be combined with x_vars/y_vars.

None
x_vars sequence of str

Column names for the columns of the grid. Must be paired with y_vars.

None
y_vars sequence of str

Column names for the rows of the grid. Must be paired with x_vars.

None
hue str or encoding

Column name to map to color across all panels.

None
kind ('scatter', 'kde', 'hist', 'reg')

Mark for the off-diagonal cells. "scatter" calls mark_point; "kde" calls mark_density; "hist" calls mark_histogram; "reg" calls mark_smooth(method="lm").

"scatter"
diag_kind ('auto', 'hist', 'kde', None, 'none')

Mark for the diagonal cells (only when vars is symmetric). "auto" resolves to "kde" (KDE is smoother and more informative than histograms for overlapping distributions). Pass None or "none" to suppress diagonal marks.

"auto"
markers str or list of str

Point-marker shape(s). A single string (e.g. "square") sets the shape on every scatter panel. A list maps each hue level to a shape via the Shape encoding. Only applies when kind="scatter".

None
height float or None

Height of each individual panel in pixels. When set alongside aspect, each panel's width is height * aspect.

None
aspect float or None

Aspect ratio per panel (width = height * aspect). Defaults to 1.0 when height is set and aspect is omitted.

None
corner bool

Render only the lower-triangle panels.

False
dropna bool

When True, drop rows with any null value in the selected variable columns before building the pairplot.

False
theme Theme

Visual theme applied to all panels.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode() on every panel template.

{}

Returns:

Type Description
RepeatChart

Grid of panels sharing the same off-diagonal and (optionally) diagonal chart templates.

Raises:

Type Description
ValueError

If kind or diag_kind is not one of the supported values.

ValueError

If both vars and x_vars/y_vars are supplied.

ValueError

If only one of x_vars / y_vars is supplied.

Examples:

>>> import ferrum as fm
>>> fm.pairplot(df)

Specific variables with KDE off-diagonal and per-species color:

>>> fm.pairplot(
...     df, vars=["sepal_length", "sepal_width", "petal_length"],
...     kind="kde", hue="species",
... )

heatmap

heatmap(data: Any, *, annot: bool = True, fmt: str = '.2f', cmap: str | None = None, linewidths: float = 0.5, linecolor: str = 'white', vmin: float | None = None, vmax: float | None = None, center: float | None = None, robust: bool = False, square: bool = False, mask: Any = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> Chart

2-D heatmap of a wide-format DataFrame.

Each row of data becomes a row of the heatmap; each numeric column becomes a column. The first non-numeric column (if any) is used as the row-label axis; rows without a label column get a synthetic integer index. The DataFrame is unpivoted to long form via Unpivot, then rendered with mark_rect and an optional annotation layer (mark_text).

Parameters:

Name Type Description Default
data DataFrame - like

Wide-format input. Numeric columns become the heatmap cells; the first non-numeric column (if present) labels the rows.

required
annot bool

Overlay cell values as text using mark_text.

True
fmt str

Python format specifier applied to cell values in the annotation layer.

".2f"
cmap str or None

Color scheme name (e.g. "blues", "viridis", "rdbu"). None (default) defers to the theme's sequential scheme.

None
linewidths float

Width of the cell border stroke in pixels. 0 disables borders.

0.5
linecolor str

Color of the cell border stroke.

"white"
vmin float or None

Minimum of the color scale domain. Overrides robust when set.

None
vmax float or None

Maximum of the color scale domain. Overrides robust when set.

None
center float or None

Value to center a diverging color scale on (maps to scale.domainMid).

None
robust bool

When True and vmin/vmax are unset, clip the color scale to the 2nd and 98th percentiles of the data.

False
square bool

Force equal width and height per cell so the heatmap is square.

False
mask array-like, "upper", "lower", or None

Cell-masking control. When "upper", only the upper triangle (including the diagonal) is shown. When "lower", only the lower triangle (including the diagonal) is shown. When an array-like boolean matrix (same shape as the numeric portion of data), cells where the mask is True are hidden.

None
theme Theme

Visual theme applied via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode().

{}

Returns:

Type Description
Chart

Possibly layered chart (mark_rect + mark_text when annot=True).

Raises:

Type Description
ValueError

If data has no numeric columns.

Examples:

>>> import ferrum as fm
>>> fm.heatmap(corr_df, cmap="rdbu", center=0)

Suppress annotations and use a custom domain:

>>> fm.heatmap(wide_df, annot=False, vmin=0, vmax=1, cmap="greens")

clustermap

clustermap(data: Any, *, method: str = 'ward', metric: str = 'euclidean', cmap: str | None = None, z_score: Any = None, standard_scale: Any = None, figsize: Any = None, dendrogram_ratio: float = 0.2, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> 'ClusterMapChart'

Clustered heatmap with row and column dendrograms.

Returns a ClusterMapChart composed of:

  • a center heatmap of the hierarchically-reordered wide-format DataFrame (Linkage + Reorder + Unpivot + mark_rect),
  • a column dendrogram (top, mark_segment, reading col_link_segments), and
  • a row dendrogram (left, mark_segment + CoordFlip, reading row_link_segments).

Parameters:

Name Type Description Default
data DataFrame - like

Wide-format input. Same layout requirements as heatmap.

required
method str

Linkage algorithm forwarded to Linkage (e.g. "ward", "average", "complete", "single").

"ward"
metric str

Distance metric forwarded to Linkage (e.g. "euclidean", "cosine", "correlation").

"euclidean"
cmap str or None

Color scheme name for the center heatmap (e.g. "magma", "viridis", "rdbu"). Forwarded to the Color encoding's scheme scale option. "magma" is preferred for dense heatmaps due to its perceptual uniformity across a wide luminance range.

None
z_score (0, 1, None)

Standardise data along rows (0) or columns (1) before clustering; forwarded to Linkage.

0
standard_scale (0, 1, None)

Normalise to [0, 1] along rows (0) or columns (1); forwarded to Linkage.

0
figsize tuple of (float, float)

Overall figure size as (width, height) in pixels, applied to the center heatmap panel via .properties().

None
dendrogram_ratio float

Fraction of the total width/height allocated to each dendrogram panel, forwarded to ClusterMapChart.

0.2
theme Theme

Visual theme applied to the center and dendrogram charts.

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode() on the center heatmap chart.

{}

Returns:

Type Description
ClusterMapChart

Compound view with center, row_dendrogram, and col_dendrogram sub-charts.

Raises:

Type Description
ValueError

If data has no numeric columns.

Examples:

>>> import ferrum as fm
>>> fm.clustermap(expr_df, method="average", cmap="rdbu", z_score=1)

Correlation matrix with euclidean ward clustering:

>>> fm.clustermap(corr_df, cmap="viridis")

jointplot

jointplot(data: Any, *, x: str, y: str, hue: Any = None, kind: str = 'scatter', marginal_kind: str = 'hist', ratio: int = 5, space: float = 0.05, xlim: Any = None, ylim: Any = None, joint_kws: Any = None, marginal_kws: Any = None, height: float | None = None, mark: dict | None = None, encode: dict | None = None, properties: dict | None = None, layers: list | None = None, theme: Any = None, **encode_kwargs: Any) -> JointChart

Joint-distribution plot with marginals.

Builds a JointChart composed of a central bivariate plot flanked by univariate marginals along the x (top) and y (right) axes.

Parameters:

Name Type Description Default
data DataFrame - like

Input data accepted by Chart(data).

required
x str

Column name for the horizontal axis (required).

required
y str

Column name for the vertical axis (required).

required
hue str or encoding

Column name to map to color in both the center and marginal charts.

None
kind ('scatter', 'kde', 'hist', 'hex', 'reg')

Mark to use for the central panel. "scatter" draws mark_point; "kde" draws mark_density; "hist" draws a 2-D histogram via Bin2D + mark_rect; "hex" draws mark_hex; "reg" layers mark_point + a mark_smooth(method="lm") fit line.

"scatter"
marginal_kind ('hist', 'kde', 'rug', 'box')

Mark to use for the marginal panels (same kind applied to both the top x-marginal and the right y-marginal).

"hist"
ratio int

Size ratio of the center panel to the marginal panels.

5
space float

Gap (in layout units) between the center and marginal panels.

0.05
xlim tuple

(min, max) domain override for the x-axis. Applied as an explicit scale domain on the center and top-marginal x encodings via X(field, scale={"domain": [min, max]}).

None
ylim tuple

(min, max) domain override for the y-axis. Applied as an explicit scale domain on the center and right-marginal y encodings via Y(field, scale={"domain": [min, max]}).

None
joint_kws dict

Extra keyword arguments forwarded to the center-panel mark call.

None
marginal_kws dict

Extra keyword arguments forwarded to the marginal mark calls.

None
height float or None

Height and width of the square central panel in pixels.

None
theme Theme

Visual theme applied to all three panels via Chart.theme().

None
mark dict

Per-layer mark overrides. For composite-mark charts, keys are layer names (e.g. {"scatter": {"opacity": 0.5}}); for single-mark charts, a flat dict of mark properties.

None
encode dict

Additional encoding kwargs merged via Chart.encode(**encode).

None
properties dict

Chart properties merged via Chart.properties(**properties) (e.g. {"width": 400, "title": "My chart"}).

None
layers list

Extra layers appended via Chart.layer(*layers).

None
**encode_kwargs Any

Additional keyword arguments forwarded to Chart.encode() on the center chart.

{}

Returns:

Type Description
JointChart

Compound view with center, top, and right sub-charts.

Raises:

Type Description
ValueError

If kind or marginal_kind is not one of the supported values.

Examples:

>>> import ferrum as fm
>>> fm.jointplot(df, x="sepal_length", y="sepal_width")

2-D histogram center with KDE marginals, colored by species:

>>> fm.jointplot(
...     df, x="sepal_length", y="petal_length",
...     kind="hist", marginal_kind="kde", hue="species",
... )

hconcat

hconcat(*charts, spacing=10.0)

Horizontal concatenation of charts.

Parameters:

Name Type Description Default
*charts Chart or _ChartLike

Two or more charts to place side-by-side.

()
spacing float

Pixel gap between adjacent charts.

10.0

Returns:

Type Description
HConcatChart

Examples:

>>> import ferrum as fm
>>> left = fm.Chart(df).mark_point().encode(x="x", y="y")
>>> right = fm.Chart(df).mark_bar().encode(x="category", y="count")
>>> fm.hconcat(left, right)

vconcat

vconcat(*charts, spacing=10.0)

Vertical concatenation of charts.

Parameters:

Name Type Description Default
*charts Chart or _ChartLike

Two or more charts to stack top-to-bottom.

()
spacing float

Pixel gap between adjacent charts.

10.0

Returns:

Type Description
VConcatChart

Examples:

>>> import ferrum as fm
>>> top = fm.Chart(df).mark_point().encode(x="x", y="y")
>>> bottom = fm.Chart(df).mark_line().encode(x="time", y="value")
>>> fm.vconcat(top, bottom)