Plots¶
A result’s figures. PlotConfig describes what is
in a panel — its traces and its axis labels, with no styling — and the renderers
here draw it. A fit’s own panels and a result decoded from the API therefore
produce the same figure.
Reach for these directly only when building panels by hand; a result object
plots itself with plot_fit_results(), which
picks a renderer by the objective’s type.
Typed plot configs and the matplotlib renderers that draw them.
A PlotConfig declares what is in a panel (its traces and labels), not
how it looks; style is decided here by trace label, so the same config renders
identically from an in-process fit and from a result decoded over the API.
render() dispatches on the objective’s type and falls back to a plain
panel grid for an unknown type, so a new server objective cannot break plotting
for an older client. Matplotlib is an optional dependency (the plot extra).
- class ionworks.pipeline.plots.PlotConfig(*, x_label: str = '', y_label: str = '', x_range: tuple[float | None, float | None] | None=None, y_range: tuple[float | None, float | None] | None=None, traces: list[PlotTrace] = <factory>)[source]¶
Bases:
BaseModelOne panel: what to draw and how to label it, with no styling.
- model_config = {'arbitrary_types_allowed': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- x_range: tuple[float | None, float | None] | None¶
Explicit
(min, max)axis bounds; either side may beNoneto auto-scale.
- classmethod from_wire(payload: dict) PlotConfig[source]¶
Build a config from a stored plot payload.
The backend persists each plot in plotly’s vocabulary (
{"type", "traces": [{"name", "x", "y"}], "layout": {"xaxis": ...}}); this maps that onto the fields above.- Parameters:
payload (dict) – One plot as returned by
GET /datafits/{id}/plot_data.- Returns:
The equivalent config.
- Return type:
- class ionworks.pipeline.plots.PlotTrace(*, label: str = '', x: Any = None, y: Any = None, color: str | None = None)[source]¶
Bases:
BaseModelOne labelled series in a panel.
- model_config = {'arbitrary_types_allowed': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- x: Any¶
x values. Any array-like matplotlib accepts.
- ionworks.pipeline.plots.error_label(variable: str) str[source]¶
Axis label for a variable’s residual, carrying its unit when it has one.
- ionworks.pipeline.plots.fit_panels(variables: list[str], x_key: str, data: dict, model: dict, *, x_label: str | None = None) list[PlotConfig][source]¶
Panels for a fit: measured against fitted per variable, then the residuals.
Residuals come last as a block, so laying the result out in
len(variables)columns puts each residual under the curve it came from.- Parameters:
variables (list of str) – Keys to plot, one panel each. A
"Name [unit]"key gives the residual panel its unit.x_key (str) – Key of the independent variable. Taken from
modelwhen it carries its own, else shared withdata.data (dict) – The measurement, keyed by variable.
model (dict) – The fitted model’s output, keyed the same way.
x_label (str, optional) – Axis label for the independent variable. Defaults to
x_key.
- Returns:
One config per variable, then one residual config per variable.
- Return type:
list of PlotConfig
- ionworks.pipeline.plots.plot_eis(plots: list[PlotConfig | dict], **kwargs) tuple[source]¶
Nyquist plot(s) for an EIS objective.
Impedance is plotted with an equal aspect ratio: a distorted Nyquist arc misrepresents the semicircle a reader is judging.
- Parameters:
plots (list of PlotConfig or dict) – The objective’s panels.
- Returns:
(fig, axes).- Return type:
- ionworks.pipeline.plots.plot_panels(plots: list[PlotConfig | dict], *, equal_aspect: bool = False, fig_axes: tuple | None = None, n_cols: int | None = None, share_x: bool = False) tuple[source]¶
Draw one panel per plot config, in a grid.
- Parameters:
plots (list of PlotConfig or dict) – The panels, in the order they should appear. A dict is coerced — a stored plot payload via
PlotConfig.from_wire(), otherwise asPlotConfigfields.equal_aspect (bool, optional) – Force a 1:1 data aspect ratio on every panel. Defaults to False.
fig_axes (tuple, optional) – An existing
(fig, axes)to draw onto, so several datasets can be overlaid on shared panels. A new figure is created when omitted.n_cols (int, optional) – Column count. Defaults to a roughly square grid. Panels fill row by row, so pass it when the order groups panels into columns.
share_x (bool, optional) – Share the x axis down each column and label only the bottom panel of each. Only meaningful with
n_cols, which is what puts panels of the same quantity in one column. Defaults to False.
- Returns:
(fig, axes)whereaxesis a flat list, one entry per panel.- Return type:
- Raises:
ValueError – If
plotsis empty.
- ionworks.pipeline.plots.render(objective_type: str | None, plots: list[PlotConfig | dict], **kwargs) tuple[source]¶
Draw an objective’s plots with the renderer for its type.
- Parameters:
objective_type (str or None) – The objective’s
typediscriminator (e.g."EIS"). An unknown or missing type falls back to a plain panel grid.plots (list of PlotConfig or dict) – The objective’s panels.
- Returns:
(fig, axes).- Return type:
- Raises:
ValueError – If
plotsis empty.