Skip to content

Scatter Plots

metrana.log_scatter records a point cloud at one step — an embedding projection, a latent-space slice, a Pareto front — as a scatter series that charts render per step. metrana.log_scatter3d is the same call with a third axis:

metrana.log_scatter(metric_name, xs, ys, step, *, x_title=None, y_title=None,
timestamp=None, scale=None, labels=None, evaluation=None)
metrana.log_scatter3d(metric_name, xs, ys, zs, step, *, x_title=None, y_title=None, z_title=None,
timestamp=None, scale=None, labels=None, evaluation=None)

step, scale, labels, and evaluation shape the series identity exactly as for standard metrics; this page covers the scatter value itself.

The coordinates are parallel equal-length arrays — numpy arrays, tensors, or plain sequences — holding 0 to 32,768 points, and every coordinate must be finite (a NaN/±inf point is unplottable, so the call rejects it):

import numpy as np
emb = project_embeddings(model) # [N, 2]
metrana.log_scatter("latents", emb[:, 0], emb[:, 1], step=100)
metrana.log_scatter3d("trajectory", pos[:, 0], pos[:, 1], pos[:, 2], step=100,
z_title="height")

One call carries the step’s full point set. Re-logging a step overwrites its set — it never appends — so growing a cloud incrementally means re-sending the whole cloud.

Empty arrays are a valid set: the step exists with “no points here” — natural when the plotted population (outliers, failed rollouts, …) is genuinely empty at that step — and, like any re-log, an empty set overwrites whatever the step held before.

2D and 3D are two distinct value kinds: a scatter metric is 2D or 3D for its lifetime, set by the first log call (log_scatter vs log_scatter3d), and cannot mix with floats or histograms under one name — the same one shape per metric rule every metric follows. A divergent call raises MetranaValidationError and sends nothing.

x_title / y_title / z_title (3D only) set the axis titles readers display. Titles are display metadata, not identity: they never distinguish series, the latest non-empty title set logged for a series wins, and an omitted title renders as a plain axis. Passing the same titles on every call is free; changing them mid-run updates what readers see:

metrana.log_scatter("latents", xs, ys, step=0, x_title="pc1", y_title="pc2")
metrana.log_scatter("latents", xs, ys, step=1) # titles stay pc1/pc2
metrana.log_scatter("latents", xs, ys, step=2, x_title="pc1-whitened", y_title="pc2")

Titles follow the label naming rules for now, so they are identifiers rather than free-form text.

Scatter steps are always explicit — there is no auto-increment. Point sets are typically logged sparsely (per epoch, every N steps), and their step axis must line up with the float series you chart them against. Steps may arrive in any order, and re-logging a step overwrites its set.