Visualization#

Backend-agnostic visualization layer.

A small intermediate representation (ChartSpec) describes what to draw; backend adapters (PlotlyAdapter, EChartsAdapter) turn the spec into Plotly figure dicts or ECharts option dicts.

This package is the shared substrate used by the DOE plots in process_improve.experiments.visualization and by the generic chart classes in process_improve.visualization.charts.

Chart specification (IR)#

Backend-agnostic chart specification (ChartSpec IR).

The intermediate representation captures what to draw - data, visual encodings, annotations - while backend adapters handle how to draw it. Inspired by Vega-Lite’s declarative approach, with DOE-specific primitives (significance thresholds, constraint regions) as first-class concepts.

Dataclasses are used over Pydantic to keep this layer dependency-free and fast to construct. All fields are JSON-serialisable via ChartSpec.to_dict().

class process_improve.visualization.spec.Encoding(field, title='', scale=ScaleType.linear, domain=None, format_str='')[source]#

Bases: object

Map a data field to a visual channel (x, y, colour, size, …).

Parameters:
  • field (str) – Column name in the layer’s row-oriented data.

  • title (str) – Human-readable axis or legend label.

  • scale (ScaleType) – Axis scale (linear, log, category).

  • domain (tuple[float, float] or None) – Explicit axis min/max override.

  • format_str (str) – Number format (e.g. ".2f").

field: str#
title: str = ''#
scale: ScaleType = 'linear'#
domain: tuple[float, float] | None = None#
format_str: str = ''#
class process_improve.visualization.spec.LayerSpec(mark, data, x=None, y=None, z=None, color=None, name='', opacity=1.0, style=<factory>)[source]#

Bases: object

A single visual layer - one trace in Plotly, one series in ECharts.

Parameters:
  • mark (MarkType) – Visual mark type (bar, line, scatter, contour, …).

  • data (list[dict]) – Row-oriented records for this layer.

  • x (Encoding or None) – Horizontal-axis encoding.

  • y (Encoding or None) – Vertical-axis encoding.

  • z (Encoding or None) – Depth / colour-intensity encoding (contour, surface, heatmap).

  • color (str or None) – Literal CSS colour string, or field name for colour encoding.

  • name (str) – Trace / series name for the legend.

  • opacity (float) – Layer opacity (0–1).

  • style (dict) – Catch-all for extra visual properties (line dash, marker size, bar width, …).

mark: MarkType#
data: list[dict[str, Any]]#
x: Encoding | None = None#
y: Encoding | None = None#
z: Encoding | None = None#
color: str | None = None#
name: str = ''#
opacity: float = 1.0#
style: dict[str, Any]#
class process_improve.visualization.spec.Annotation(annotation_type, axis='y', value=None, value_end=None, label='', style=<factory>)[source]#

Bases: object

An overlay annotation on a chart panel.

Parameters:
  • annotation_type (AnnotationType) – What kind of annotation this is.

  • axis (str) – "x" or "y" - which axis the annotation references.

  • value (float or None) – Position for reference lines / thresholds.

  • value_end (float or None) – End position for bands / regions.

  • label (str) – Annotation text label.

  • style (dict) – Visual overrides (color, dash, width, …).

annotation_type: AnnotationType#
axis: str = 'y'#
value: float | None = None#
value_end: float | None = None#
label: str = ''#
style: dict[str, Any]#
process_improve.visualization.spec.significance_threshold(value, *, alpha=0.05, label=None, name='ME')[source]#

Create a DOE significance-threshold annotation.

Used on Pareto and half-normal plots to indicate the margin of error (ME) or simultaneous margin of error (SME) from Lenth’s method.

Parameters:
  • value (float) – Threshold position on the y-axis.

  • alpha (float) – Significance level (for the label).

  • label (str or None) – Override label (default: "ME (α=0.05)").

  • name (str) – Threshold name ("ME" or "SME").

Return type:

Annotation

process_improve.visualization.spec.constraint_region(*, x_min=None, x_max=None, y_min=None, y_max=None, label='Infeasible')[source]#

Create a DOE constraint-region annotation.

Used on contour and overlay plots to shade infeasible areas.

Parameters:
  • x_min (float or None) – Region boundaries.

  • x_max (float or None) – Region boundaries.

  • y_min (float or None) – Region boundaries.

  • y_max (float or None) – Region boundaries.

  • label (str) – Region label.

Return type:

Annotation

class process_improve.visualization.spec.PanelSpec(layers=<factory>, annotations=<factory>, title='', x_title='', y_title='', z_title='', secondary_y=False, secondary_y_title='', width=700, height=500, backend_hints=<factory>)[source]#

Bases: object

A single chart panel - becomes one Plotly subplot or ECharts grid.

Parameters:
  • layers (list[LayerSpec]) – Visual layers drawn in this panel.

  • annotations (list[Annotation]) – Overlaid annotations.

  • title (str) – Panel title.

  • x_title (str) – Horizontal-axis label.

  • y_title (str) – Vertical-axis label.

  • z_title (str) – Depth-axis label (3D plots only).

  • secondary_y (bool) – Whether a secondary y-axis is needed.

  • secondary_y_title (str) – Label for the secondary y-axis.

  • width (int) – Panel width in pixels.

  • height (int) – Panel height in pixels.

  • backend_hints (dict) – Escape hatch for backend-specific options.

layers: list[LayerSpec]#
annotations: list[Annotation]#
title: str = ''#
x_title: str = ''#
y_title: str = ''#
z_title: str = ''#
secondary_y: bool = False#
secondary_y_title: str = ''#
width: int = 700#
height: int = 500#
backend_hints: dict[str, Any]#
class process_improve.visualization.spec.ChartSpec(panels=<factory>, title='', plot_type='', layout='single', columns=2, linked=False, metadata=<factory>, link_group=None, point_ids=None)[source]#

Bases: object

Top-level chart specification - the IR that adapters consume.

A ChartSpec may contain one or more PanelSpec panels. Single-panel charts (Pareto, contour, …) have len(panels) == 1. Multi-panel charts (diagnostic trio, linked contours) have 2–4 panels with a grid layout.

Parameters:
  • panels (list[PanelSpec]) – One or more chart panels.

  • title (str) – Overall chart / dashboard title.

  • plot_type (str) – DOE plot type name (for metadata).

  • layout (str) – "single", "row", "column", or "grid".

  • columns (int) – Number of columns for grid layout.

  • linked (bool) – Whether panels share brush / zoom interactions.

  • metadata (dict) – Extra metadata passed through to the output.

  • link_group (str or None) – Cross-chart linking key. Charts that share this key form a brushing group: a selection in any member highlights the matching point_ids in the others. Frontends read this from the rendered option dict (option["__link_group"] in ECharts).

  • point_ids (list[str] or None) – Stable per-observation identifiers aligned with the points emitted by this chart. Paired with link_group by the frontend link coordinator. None means the chart is not linkable.

panels: list[PanelSpec]#
title: str = ''#
plot_type: str = ''#
layout: str = 'single'#
columns: int = 2#
linked: bool = False#
metadata: dict[str, Any]#
point_ids: list[str] | None = None#
to_dict()[source]#

Serialise the entire spec to a plain dict (JSON-safe).

Enum values are converted to their string representations.

Return type:

dict[str, Any]

to_data_dict()[source]#

Extract computed data arrays from the spec.

Returns a lightweight dict containing just the raw data from each panel’s layers - useful when the consumer wants to render with a custom frontend.

Return type:

dict[str, Any]

Enums and type constants for chart specs.

These enums define the vocabulary for backend-agnostic chart specs: mark types, scale types, annotation types, and the DOE-specific plot types. The DOEPlotType enum lists plot-type keys used by visualize_doe(); other enums are shared by generic chart classes as well.

class process_improve.visualization.types.MarkType(value)[source]#

Bases: str, Enum

Visual mark used in a layer.

bar = 'bar'#
line = 'line'#
scatter = 'scatter'#
contour = 'contour'#
heatmap = 'heatmap'#
surface = 'surface'#
area = 'area'#
text = 'text'#
wireframe = 'wireframe'#
boxplot = 'boxplot'#
class process_improve.visualization.types.ScaleType(value)[source]#

Bases: str, Enum

Axis scale type.

linear = 'linear'#
log = 'log'#
category = 'category'#
class process_improve.visualization.types.AnnotationType(value)[source]#

Bases: str, Enum

Annotation overlay type.

reference_line = 'reference_line'#
significance_threshold = 'significance_threshold'#
constraint_region = 'constraint_region'#
reference_band = 'reference_band'#
label = 'label'#
class process_improve.visualization.types.DOEPlotType(value)[source]#

Bases: str, Enum

All 20 supported DOE plot types plus the diagnostic panel.

pareto = 'pareto'#
half_normal = 'half_normal'#
daniel = 'daniel'#
main_effects = 'main_effects'#
interaction = 'interaction'#
perturbation = 'perturbation'#
residuals_vs_fitted = 'residuals_vs_fitted'#
normal_probability = 'normal_probability'#
residuals_vs_order = 'residuals_vs_order'#
box_cox = 'box_cox'#
contour = 'contour'#
surface_3d = 'surface_3d'#
prediction_variance = 'prediction_variance'#
cube_plot = 'cube_plot'#
desirability_contour = 'desirability_contour'#
overlay = 'overlay'#
ridge_trace = 'ridge_trace'#
steepest_ascent_path = 'steepest_ascent_path'#
fds_plot = 'fds_plot'#
power_curve = 'power_curve'#

Backend adapters#

ECharts backend adapter: ChartSpec → ECharts option dict.

Produces raw Python dicts that match the ECharts option specification. No pyecharts dependency - dicts are JSON-serialisable and can be passed directly to echarts.setOption() on the SvelteKit frontend.

class process_improve.visualization.adapters.echarts_adapter.EChartsAdapter[source]#

Bases: AbstractAdapter

Translate a ChartSpec to an ECharts option dict.

render(spec)[source]#

Convert the full chart spec to an ECharts option dict.

Parameters:

spec (ChartSpec) – The backend-agnostic chart specification.

Returns:

ECharts option dict with title, xAxis, yAxis, series, etc.

Return type:

dict

render_panel(panel)[source]#

Convert a single panel to an ECharts option dict.

Parameters:

panel (PanelSpec) – One chart panel.

Returns:

ECharts option dict.

Return type:

dict

Plotly backend adapter: ChartSpec → Plotly figure dict.

Converts a ChartSpec into a Plotly-compatible dict that can be passed directly to plotly.graph_objects.Figure(data_dict) or serialised to JSON via json.dumps.

class process_improve.visualization.adapters.plotly_adapter.PlotlyAdapter[source]#

Bases: AbstractAdapter

Translate a ChartSpec to a Plotly figure dict.

render(spec)[source]#

Convert the full chart spec to a Plotly figure dict.

Parameters:

spec (ChartSpec) – The backend-agnostic chart specification.

Returns:

Plotly figure dict with data and layout keys.

Return type:

dict

render_panel(panel)[source]#

Convert a single panel to a Plotly figure dict.

Parameters:

panel (PanelSpec) – One chart panel.

Returns:

Plotly figure dict.

Return type:

dict