GridPlot¶
Compose multiple plots into a grid layout with independent or shared axes.
Class: diffract.viz.plots.subplots.GridPlot (also
diffract.viz.plots.GridPlot).
Basic usage¶
from diffract.viz.data import FieldRef
from diffract.viz.plots.boxplot import BoxPlot
from diffract.viz.plots.subplots import GridPlot, SubplotSpec
with session:
grid = GridPlot(
subplots=[
SubplotSpec(
row=1, col=1, title="Stable Rank",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("model_id")),
),
SubplotSpec(
row=1, col=2, title="Frob Norm",
plot=BoxPlot(y=FieldRef("frob_norm"), x=FieldRef("model_id")),
),
],
make_subplots_kwargs={"shared_yaxes": False},
)
fig = session.viz.draw(plot=grid)
Example: Side-by-side model comparison¶
grid = GridPlot(
subplots=[
SubplotSpec(
row=1, col=1,
title="Model A",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("layer_id")),
session_filter={"model_ids": ["model_a"]},
),
SubplotSpec(
row=1, col=2,
title="Model B",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("layer_id")),
session_filter={"model_ids": ["model_b"]},
),
],
make_subplots_kwargs={"shared_yaxes": True},
)
Example: 2x2 grid with mixed plot types¶
from diffract.viz.plots.scatter import ScatterPlot
from diffract.viz.plots.violin import ViolinPlot
grid = GridPlot(
subplots=[
SubplotSpec(
row=1, col=1, title="Stable Rank",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("model_id")),
),
SubplotSpec(
row=1, col=2, title="Frob Norm",
plot=BoxPlot(y=FieldRef("frob_norm"), x=FieldRef("model_id")),
),
SubplotSpec(
row=2, col=1, title="Scatter",
plot=ScatterPlot(x=FieldRef("frob_norm"), y=FieldRef("stable_rank")),
),
SubplotSpec(
row=2, col=2, title="ESD",
plot=ViolinPlot(y=FieldRef("esd"), x=FieldRef("model_id")),
),
],
make_subplots_kwargs={
"horizontal_spacing": 0.08,
"vertical_spacing": 0.12,
},
)
SubplotSpec¶
Specification for a single subplot
(diffract.viz.plots.subplots.SubplotSpec):
from diffract.viz.plots.subplots import SubplotSpec
spec = SubplotSpec(
row=1, # row position (1-indexed)
col=2, # column position (1-indexed)
title="My Plot", # subplot title
plot=BoxPlot(...), # any Plot object
session_filter=None, # optional per-subplot session filter
value_filter=None, # optional per-subplot value filter
)
SubplotSpec fields: row, col, title, plot, session_filter,
value_filter, and filter (a backward-compatible alias for
session_filter).
Per-subplot session filtering¶
Each subplot can filter session data independently via session_filter
(forwarded to Session.filter(...)):
SubplotSpec(
row=1, col=1,
title="Attention Layers",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("layer_id")),
session_filter={
"model_ids": ["model_a"],
"param_types": ["attn"],
},
)
Valid session_filter keys:
Key |
Description |
|---|---|
|
List of parameter UIDs |
|
List of parameter names |
|
List of parameter types |
|
List of model IDs |
Per-subplot value filtering¶
value_filter is merged into the child plot’s value_filter for that subplot
only:
SubplotSpec(
row=1, col=1,
title="Filtered",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("model_id")),
value_filter={"stable_rank": (">", 10.0)},
)
GridPlot parameters¶
Parameter |
Type |
Description |
|---|---|---|
|
|
List of subplot specifications |
|
|
Arguments for |
GridPlot has no theme field. Pass a Theme when rendering:
from diffract.viz.styling import DARK_THEME
fig = session.viz.draw(plot=grid, theme=DARK_THEME)
make_subplots_kwargs¶
Common options for plotly.subplots.make_subplots (the rows, cols, and
subplot_titles keys are ignored — they are derived from the specs):
Option |
Type |
Description |
|---|---|---|
|
|
Share X axes ( |
|
|
Share Y axes ( |
|
|
Horizontal space between subplots |
|
|
Vertical space between subplots |
|
|
Relative widths of columns |
|
|
Relative heights of rows |
make_subplots_kwargs={
"shared_yaxes": True,
"horizontal_spacing": 0.05,
"vertical_spacing": 0.1,
"column_widths": [0.6, 0.4], # first column wider
}
YAML configuration¶
plot:
_target_: diffract.viz.plots.subplots.GridPlot
make_subplots_kwargs:
shared_yaxes: true
horizontal_spacing: 0.08
subplots:
- _target_: diffract.viz.plots.subplots.SubplotSpec
row: 1
col: 1
title: "Model A"
plot:
_target_: diffract.viz.plots.boxplot.BoxPlot
y: stable_rank
x: layer_id
session_filter:
model_ids:
- model_a
- _target_: diffract.viz.plots.subplots.SubplotSpec
row: 1
col: 2
title: "Model B"
plot:
_target_: diffract.viz.plots.boxplot.BoxPlot
y: stable_rank
x: layer_id
session_filter:
model_ids:
- model_b
Parametric grids¶
Instead of listing every SubplotSpec by hand, a grid can be generated from a
plot template plus row/column axis binds. The building blocks live in
diffract.viz.plots.subplots:
build_bound_grid(*, plot_template, row=None, col=None, cell_rules=None, title_template=None, make_subplots_kwargs=None, theme=None, base_session_filter=None, base_value_filter=None)returns aGridPlotwith auto-generatedSubplotSpecentries.GridAxisBind(target=..., key=..., values=..., labels=None, op=None)maps a sequence of values onto rows or columns.targetselects what each value overrides:"plot"(a plot attribute),"session_filter"(aSubplotSpec.session_filterkey), or"value_filter"(aSubplotSpec.value_filterkey;opturns bare thresholds into(op, threshold)conditions).GridCellRule(selector=..., plot=None, plot_format=None, session_filter=None, value_filter=None)applies extra overrides to selected cells; itsCellSelectortargets"all","first_row","last_row","first_col","last_col", or explicitrow/colindices.
At least one axis bind (row or col) is required. For each cell the plot
template is deep-copied, the row and column binds are applied, matching
cell_rules are applied in order (last write wins), and a SubplotSpec is
created.
The session wrapper session.viz.bound_grid(...) takes the same arguments
(plus theme/theme_path) and renders the grid in one call. For plot binds
targeting FieldRef plot attributes, it converts plain string bind values into
FieldRef objects automatically:
from diffract.viz.data import FieldRef
from diffract.viz.plots.boxplot import BoxPlot
from diffract.viz.plots.subplots import GridAxisBind
with session:
fig = session.viz.bound_grid(
plot_template=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("model_id")),
row=GridAxisBind(
target="plot",
key="y",
values=["stable_rank", "frob_norm"],
labels=["stable_rank", "frob_norm"],
),
col=GridAxisBind(
target="session_filter",
key="model_ids",
values=[["baseline"], ["finetuned"]],
labels=["baseline", "finetuned"],
),
make_subplots_kwargs={"shared_yaxes": "rows"},
)
This produces a 2×2 grid — one metric per row, one model per column — with
titles like "stable_rank | baseline" (the default title_template is
"{row_label} | {col_label}" when both binds are present).
The repository contains worked YAML examples of bound grids under
notebooks/configs/plots/: the grid_*.yaml configs, the plot templates in
templates/, and the reusable FieldRef definitions in refs/.
How it works¶
Determines grid dimensions from the max row/col across specs.
Creates a Plotly subplots grid via
make_subplots().For each
SubplotSpec:Applies
session_filterif specified (creates a filtered session view).Merges
value_filterinto the child plot for that subplot.Renders the child plot.
Remaps its coloraxis to avoid conflicts across subplots.
Adds traces to the grid at the specified position.
Deduplicates legend entries.
Applies the theme (when passed to
render) to the whole figure.
Coloraxis handling¶
Each subplot’s coloraxis is automatically remapped to a unique name, preventing color conflicts when multiple subplots use continuous color mapping (e.g., jitter coloring).
Notes¶
Row/column indices are 1-based, matching the Plotly
make_subplotsconvention.Grid dimensions are computed automatically from the specs.
make_subplots_kwargsmay includerows/cols, but they are overridden.Each child plot is rendered independently, then composed.
Common patterns¶
Compare models side-by-side¶
models = ["baseline", "finetuned", "pruned"]
subplots = [
SubplotSpec(
row=1, col=i + 1, title=model,
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("layer_id")),
session_filter={"model_ids": [model]},
)
for i, model in enumerate(models)
]
grid = GridPlot(subplots=subplots, make_subplots_kwargs={"shared_yaxes": True})
Dashboard-style layout¶
from diffract.viz.plots.sparkline import SparklinePlot
from diffract.viz.plots.heatmap import HeatmapPlot
grid = GridPlot(
subplots=[
SubplotSpec(
row=1, col=1, title="Overview",
plot=BoxPlot(y=FieldRef("stable_rank"), x=FieldRef("model_id")),
),
SubplotSpec(
row=1, col=2, title="Scatter",
plot=ScatterPlot(x=FieldRef("frob_norm"), y=FieldRef("stable_rank")),
),
SubplotSpec(
row=2, col=1, title="By Layer",
plot=SparklinePlot(y=FieldRef("stable_rank"), x=FieldRef("layer_id")),
),
SubplotSpec(
row=2, col=2, title="Heatmap",
plot=HeatmapPlot(
z=FieldRef("stable_rank"),
x=FieldRef("head_id"),
y=FieldRef("layer_id"),
),
),
],
make_subplots_kwargs={"horizontal_spacing": 0.1, "vertical_spacing": 0.15},
)
See also¶
Plot Types — Overview and the
UpdateFigurewrapperStyling — Grid-wide theming