Scatter Plots
A scatter series stores a point cloud per step, not a number.
Unlike histograms there is no reduced reading: scatter series define no reductions, so
fetch_scatter_series is the only endpoint serving them.
Whole point sets
Section titled “Whole point sets”frame = client.fetch_scatter_series("run-001", "latents")The frame is long — index (run, series, step), one row per step, each cell holding that step’s whole
coordinate array:
xs ysrun series steprun-001 latents 0 [0.12, -1.4, ...] [0.55, 0.21, ...] 100 [0.08, -0.9, ...] [0.61, 0.18, ...]xs and ys are float64 arrays of equal length. A 3D series adds a zs column; on a fetch that matches
both kinds, 2D rows carry None there, so the two stay structurally distinct. One fetch serves both scatter
kinds by default — pass kind= to narrow:
from metrana.query import SeriesValueKind
client.fetch_scatter_series("run-001", "trajectory", kind=SeriesValueKind.SCATTER_3D)Axis titles
Section titled “Axis titles”The titles the run logged come back in
frame.attrs["axis_titles"], keyed by (run, series) — a dict with "x"/"y"/"z" entries for the titles
that exist (a title never logged is simply absent):
titles = frame.attrs["axis_titles"].get(("run-001", "latents"), {})ax.set_xlabel(titles.get("x", ""))They are also on SeriesDefinition.metadata_labels (under the xt/yt/zt keys) when you go through
list_series_definitions.
Step extents
Section titled “Step extents”include_extents=True attaches each series’ extents as frame.attrs["extents"], keyed by (run, series).
Each value is a ScatterSeriesExtent:
| Field | Meaning |
|---|---|
first_step |
Lowest step the series has, ignoring the steps selection. |
last_step |
Highest step the series has, ignoring the steps selection. |
points_count |
Upper bound on the number of steps — counted before deduplication, so re-logged steps inflate it. |
data_points_count |
Upper bound on the total number of individual points across all steps — a sizing hint for range fetches. |
As for histograms, the extent is independent of the steps you asked for: fetch just the last point set and
you still learn the series’ full range, enough to render a step slider without a second scan.
from metrana.query import LastSteps
frame = client.fetch_scatter_series("run-001", "latents", steps=LastSteps(1), include_extents=True)extent = frame.attrs["extents"][("run-001", "latents")]slider_range = (extent.first_step, extent.last_step)No reduced reading
Section titled “No reduced reading”There is no scatter counterpart of reduce_histogram — no single float meaningfully summarises a point
cloud, so scatter series never appear on the float endpoints, and the summary listings return only their
step skeleton. A selector carrying a reducer is rejected at the call.