xwm.plots¶
Figures, GIFs and JSON/LaTeX tables, with each palette's categorical limit enforced in code rather than documented. See Figures and tables.
Figures, animations and result tables.
Two palettes, picked by what the chart does: blue-orange (Wong's
colourblind-safe family) for curves -- losses, training histories, error by
horizon -- and viridis for magnitude and for many-way categorical
comparisons. xwm.plots.style records the measured separation of each and
enforces its series limit rather than documenting it.
Matplotlib and Pillow are optional dependencies (pip install xwm[plots]);
importing this module without them succeeds, and the error surfaces only when a
helper that needs them is actually called.
Modules:
| Name | Description |
|---|---|
curves |
Training-curve and spectrum plots. |
export |
Writing figures and animated GIFs to disk. |
style |
Plot palettes, with each one's categorical limit enforced in code. |
tables |
Result tables and metrics, as JSON and LaTeX. |
visualize |
Visualising frames, masks and latents. |
Functions:
| Name | Description |
|---|---|
plot_bars |
A bar chart for comparing a single metric across a few configurations. |
plot_history |
Plot metrics from |
plot_horizon |
Error-versus-horizon curves -- the compounding-error picture. |
plot_spectra |
Overlay several embedding spectra, one line per named model. |
plot_spectrum |
Plot the normalised singular-value spectrum of an embedding matrix. |
frames_to_uint8 |
Normalise a frame sequence to |
save_figure |
Save a matplotlib figure, creating parent directories. |
save_gif |
Write an animated GIF. |
tile_frames |
Lay several frame sequences side by side into one sequence. |
upscale |
Nearest-neighbour integer upscale, so pixels stay crisp rather than blurred. |
palette_colors |
|
plot_style |
Apply the xwm style for one block, leaving global rcParams untouched. |
rc_params |
Matplotlib rcParams for the xwm look: recessive axes, thin marks. |
series_style |
Colour, marker and line style for series |
use_viridis |
Apply the xwm style globally. Call once at the top of a script. |
viridis_colors |
|
viridis_style |
Deprecated alias for |
escape_latex |
Escape LaTeX special characters. Metric names like |
format_cell |
Render one cell: real numbers via |
jsonable |
Convert a value to something |
latex_table |
A |
markdown_table |
A GitHub-flavoured Markdown table, column-aligned for readability. |
save_json |
Write |
save_metrics |
Write a flat mapping of scalar metrics to |
save_table |
Write |
table_to_dict |
The JSON payload for a table: full-precision values keyed by column. |
plot_frames |
Draw a strip of |
plot_latent_pca |
Scatter embeddings on their first two principal components. |
plot_mask |
Overlay a token mask on an image, dimming the masked patches. |
plot_rollout |
Compare a real trajectory against an imagined one, frame by frame. |
plot_bars
¶
plot_bars(labels: Sequence[str], values: Sequence[float], *, ax=None, title: str | None = None, ylabel: str | None = None, annotate: bool = True, horizontal: bool = True, palette: str = MAGNITUDE_PALETTE)
A bar chart for comparing a single metric across a few configurations.
Horizontal by default: configuration names are long, and rotated tick labels are harder to read than a horizontal bar's left-aligned label.
Source code in xwm/plots/curves.py
plot_history
¶
plot_history(history: Sequence[dict[str, float]], *, keys: Sequence[str] | None = None, ax=None, logy: bool = False, title: str | None = None, ylabel: str = 'loss', label_last: bool = True, palette: str = CURVE_PALETTE)
Plot metrics from xwm.training.Trainer.fit's history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
history
|
Sequence[dict[str, float]]
|
the list of metric dicts |
required |
keys
|
Sequence[str] | None
|
which metrics to draw; defaults to every |
None
|
label_last
|
bool
|
annotate each series' final value directly on the plot, so the reader does not have to match a colour to a legend entry to learn the number that matters. |
True
|
Source code in xwm/plots/curves.py
plot_horizon
¶
plot_horizon(horizons: Sequence[int], series: dict[str, Sequence[float]], *, ax=None, title: str = 'Rollout error by horizon', ylabel: str = 'latent L1 error', palette: str = CURVE_PALETTE)
Error-versus-horizon curves -- the compounding-error picture.
Source code in xwm/plots/curves.py
plot_spectra
¶
plot_spectra(named: dict[str, Array], *, ax=None, title: str = 'Embedding spectra', palette: str = MAGNITUDE_PALETTE)
Overlay several embedding spectra, one line per named model.
The single most legible collapse diagnostic: a collapsed encoder's spectrum plunges after a few directions while a healthy one decays gently.
Source code in xwm/plots/curves.py
plot_spectrum
¶
plot_spectrum(z: Array, *, ax=None, title: str | None = None, label: str | None = None, palette: str = CURVE_PALETTE)
Plot the normalised singular-value spectrum of an embedding matrix.
A healthy representation decays gently; a collapsing one falls off a cliff after a handful of directions.
Source code in xwm/plots/curves.py
frames_to_uint8
¶
Normalise a frame sequence to (T, H, W, 3) uint8.
Accepts channels-first (T, C, H, W) or channels-last (T, H, W, C),
grayscale or RGB, float in [0, 1] or already uint8.
Source code in xwm/plots/export.py
save_figure
¶
Save a matplotlib figure, creating parent directories.
Source code in xwm/plots/export.py
save_gif
¶
save_gif(path: str | Path, frames: Array | Sequence[Array], *, fps: int = 8, scale: int = 1, labels: Sequence[str] | None = None, loop: int = 0, colors: int = 256, dither: bool = False) -> Path
Write an animated GIF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frames
|
Array | Sequence[Array]
|
one |
required |
fps
|
int
|
playback rate. |
8
|
scale
|
int
|
integer upscale factor. Prefer rendering at the size you want -- nearest-neighbour upscaling turns every source pixel into a block and cannot add detail. Useful only for genuinely tiny sources such as the 32x32 sprite world. |
1
|
labels
|
Sequence[str] | None
|
per-panel captions, drawn above each tile. |
None
|
loop
|
int
|
|
0
|
colors
|
int
|
palette size, at most 256 (a GIF limit). |
256
|
dither
|
bool
|
diffuse quantisation error. Off by default: on smooth renders it reads as grain, and with a 256-colour palette there is little error left to diffuse. |
False
|
A single palette is computed across all frames. Quantising each frame independently -- what Pillow does by default -- gives every frame its own palette, so colours shift frame to frame and the animation shimmers even when the underlying pixels barely change.
Source code in xwm/plots/export.py
tile_frames
¶
tile_frames(sequences: Sequence[Array], *, labels: Sequence[str] | None = None, scale: int = 4, pad: int = 2, label_height: int = 14) -> ndarray
Lay several frame sequences side by side into one sequence.
Sequences of differing length are truncated to the shortest, so a comparison strip never silently pairs frame 5 of one rollout with frame 9 of another.
Source code in xwm/plots/export.py
upscale
¶
Nearest-neighbour integer upscale, so pixels stay crisp rather than blurred.
palette_colors
¶
n hex colours from a named palette, in a fixed order.
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Source code in xwm/plots/style.py
plot_style
¶
Apply the xwm style for one block, leaving global rcParams untouched.
Source code in xwm/plots/style.py
rc_params
¶
Matplotlib rcParams for the xwm look: recessive axes, thin marks.
Source code in xwm/plots/style.py
series_style
¶
Colour, marker and line style for series index of n_series.
Colour follows the series' identity (its index), never its rank, so filtering the chart never repaints the survivors.
Source code in xwm/plots/style.py
use_viridis
¶
Apply the xwm style globally. Call once at the top of a script.
viridis_colors
¶
n hex colours sampled evenly from viridis, in a fixed order.
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Source code in xwm/plots/style.py
viridis_style
¶
Deprecated alias for plot_style, kept for callers that used it.
escape_latex
¶
format_cell
¶
Render one cell: real numbers via float_format, everything else via str.
Unwraps 0-d NumPy and JAX scalars first. They are not Python float, so a
bare isinstance check silently lets them through unformatted -- and they
are exactly what a training loop hands to a results table.
Source code in xwm/plots/tables.py
jsonable
¶
Convert a value to something json can encode, without rounding.
NumPy and JAX scalars become Python numbers; non-finite floats become
None, since JSON has no NaN or Infinity and emitting bare NaN
produces a file that strict parsers reject.
Source code in xwm/plots/tables.py
latex_table
¶
latex_table(headers: Sequence[str], rows: Sequence[Row], *, caption: str | None = None, label: str | None = None, align: str | None = None, float_format: str = '{:.4f}', escape: bool = True, booktabs: bool = True) -> str
A tabular (optionally wrapped in table) using booktabs rules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
align
|
str | None
|
column spec such as |
None
|
escape
|
bool
|
escape LaTeX specials in cells. Turn it off to pass math through. |
True
|
booktabs
|
bool
|
use |
True
|
Source code in xwm/plots/tables.py
markdown_table
¶
A GitHub-flavoured Markdown table, column-aligned for readability.
For printing to a terminal or pasting into a README; save_table
writes JSON and LaTeX to disk, not this.
Source code in xwm/plots/tables.py
save_json
¶
Write payload as pretty-printed JSON, creating parent directories.
Source code in xwm/plots/tables.py
save_metrics
¶
save_table
¶
save_table(path_stem: str | Path, headers: Sequence[str], rows: Sequence[Row], *, caption: str | None = None, label: str | None = None, align: str | None = None, float_format: str = '{:.4f}') -> dict[str, Path]
Write <stem>.json (full precision) and <stem>.tex (formatted).
Returns a mapping from extension to the path written.
Source code in xwm/plots/tables.py
table_to_dict
¶
table_to_dict(headers: Sequence[str], rows: Sequence[Row], *, caption: str | None = None, label: str | None = None) -> dict[str, Any]
The JSON payload for a table: full-precision values keyed by column.
Source code in xwm/plots/tables.py
plot_frames
¶
plot_frames(frames: Array, *, titles=None, max_frames: int = 12, scale: float = 1.3, suptitle: str | None = None)
Draw a strip of (T, C, H, W) frames.
scale is inches per panel. Text scales with it: a strip sized to show a
768 px render natively is ~30 inches wide, where 8 pt titles are unreadable
and a fixed-height suptitle lands on top of them.
Source code in xwm/plots/visualize.py
plot_latent_pca
¶
plot_latent_pca(z: Array, *, labels: Array | None = None, ax=None, label_name: str = 'value', title: str | None = None)
Scatter embeddings on their first two principal components.
labels is a continuous quantity (an agent coordinate, a joint angle),
so it is encoded with the viridis ramp and a colourbar -- magnitude, not
identity. If the structure the encoder learned corresponds to that
quantity, the scatter shows a smooth gradient rather than a blob.
Source code in xwm/plots/visualize.py
plot_mask
¶
Overlay a token mask on an image, dimming the masked patches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
Array
|
|
required |
mask_idx
|
Array
|
flat token indices considered visible. |
required |
grid
|
tuple[int, int]
|
|
required |
Source code in xwm/plots/visualize.py
plot_rollout
¶
Compare a real trajectory against an imagined one, frame by frame.
imagined is optional because a latent world model has nothing to render;
pass decoded frames only if you have a decoder. Otherwise use this for the
ground-truth strip and report latent distances numerically.