Saving, panels and recipes

Save at a known physical size and record the information needed to regenerate the plot.

4 min readPlotting

Save a plot

fp.save(fig, "plots/result.svg") writes an SVG, a semantic manifest (result.fluxplot.json) and a regeneration recipe (result.recipe.json). For a 3D scene it writes a GLB instead of an SVG. Keep these files together. The API reference lists every save option.

Physical size and named panels

Set the figure size before saving. Matplotlib’s figsize is in inches: divide millimetres by 25.4. For a 90 × 65 mm plot, use plt.subplots(figsize=(90 / 25.4, 65 / 25.4), layout="constrained"). The saved physical size is available when you insert the plot in Flux.

Name each panel when a plot has several axes. These names keep its parts identifiable if you rearrange the layout:

import matplotlib.pyplot as plt
import fluxplot as fp

fig, axes = plt.subplots(1, 2, layout="constrained")
for name, ax in zip(["baseline", "followup"], axes):
    fp.panel(ax, name)               # stable even when the layout changes
    fp.line(ax, [0, 1, 2], [1, 3, 2], series="control")
fp.save(fig, "plots/comparison.svg")

A plot with a single axes keeps IDs such as control.line. With several axes (including twins and insets), IDs are namespaced by panel: the explicit names above produce panel.baseline.control.line. Unnamed panels are numbered in layout order, so name them whenever identities must survive rearrangement. Colorbars belong to their source panel and are not counted as additional plotting axes.

Saved data, coordinates and panel identities

Saving captures the current artist state: edit a line with set_data, remove an annotation, then save again. Scientific numbers retain their precision; NaN and masked observations become JSON null at their original indices. Missing line observations remain gaps. Nonfinite recipe parameters are rejected before any existing output file is replaced. Normal figure closing and garbage collection release the registry.

Use ordinary Matplotlib scalar inputs, categorical bars and datetime coordinates. barh shares bar’s orientation/baseline metadata. Histograms record bin edges, heights, count/density, weighting and cumulative settings; counts remains the legacy height key. Line markers inherit size, colour, opacity, z-order and markevery. Numeric exported coordinates use Matplotlib’s converted units, with display tick labels and date epoch information alongside them.

Axis tick groups include visible major and minor marks on both sides, with matching label and gridline groups. Existing major bottom/left IDs are preserved; minor and opposite-side components use minor and secondary ID segments. Named colorbars likewise expose .ticks and .tick-labels groups, include the visible tick side, and report only major tick locations inside the displayed range. Colorbar parts carry explicit text/line/shape kinds, and tick marks export as measurable paths.

The manifest’s components inventory includes every repeated role, and both the parts tree and build order use that inventory. Coordinates are captured after layout with the SVG renderer. projection, axis supported, and series capabilities.dataMorph describe whether data-space interpolation is exact. Flux interpolates supported line/scatter plots per panel and preserves gaps; unsupported scales, polar/3D projections, raster layers and composite marks use a complete transition. A 3D scatter retains group identity without claiming depth-sorted point indices.

For multi-hue Seaborn output, pass the plotting adapter: fp.tag_seaborn(ax, plot="histplot"), plot="lineplot", plot="barplot", etc. Distribution adapters account for reversed hue draw order. Explicit series=[...] means artist draw order. Ambiguous automatic tagging warns and leaves addressable extras; it never guesses scientific identity from colour.

Recipes and parameters

A recipe records the producing script, parameters, inputs and output. An SVG stays viewable without its analysis environment; regeneration needs the recorded script and dependencies. Flux’s Regenerate control and flux rerun-plot use this information.

from pathlib import Path
import fluxplot as fp

settings = fp.params({"window": 12, "threshold": 0.5})
# Use settings["window"] and settings["threshold"] in your analysis.
# After creating fig:
fp.save(fig, "plots/result.svg", recipe={
    "script": str(Path(__file__).resolve()),
    "params": settings,
    "inputs": ["data/measurements.csv"],
})

This is a pattern to add to your own script: fig and the input file must exist. fp.params reads overrides from FLUX_PARAMS; a normal script run uses your defaults. Keep scientifically meaningful choices as explicit parameters. Colour-scale controls are recorded separately under __fluxplot__; see colour controls.

A recipe can also override args, cwd and output; paths for cwd and output resolve relative to the recipe directory. When one script saves several plots, setting FLUXPLOT_ONLY to a comma-separated list of plot names (wildcards such as fig2* work) skips every other save before layout or file output; flux rerun-plot <recipe> --only sets it for you.

Check and regenerate

flux validate-plot plots/result.svg
flux rerun-plot plots/result.recipe.json

Keep series names and point keys stable across versions so styling, highlights and data morphs still refer to the same things. See semantic plots and source links for how updates reach an existing figure.

Search the docs

Search guides, workspaces, and reference topics.

↑ ↓ to move · Enter to open · Esc to close