FigRecipe API Reference
The full public surface of figrecipe is documented inline below
via automodule. The __all__ declaration in
figrecipe/__init__.py is the single source of truth for what
appears here; do NOT add explicit autofunction / autoclass
directives below — Sphinx already discovers them through
automodule :members: and a second declaration triggers
duplicate object description warnings (treated as errors on PR
builds).
figrecipe - Record and reproduce matplotlib figures.
A lightweight library for capturing matplotlib plotting calls and reproducing figures from saved recipes.
Usage
>>> import figrecipe as fr
>>> fig, ax = fr.subplots()
>>> ax.plot(x, y, id='my_data')
>>> fr.save(fig, 'recipe.yaml')
Examples
Recording a figure:
>>> import figrecipe as fr
>>> import numpy as np
>>>
>>> x = np.linspace(0, 10, 100)
>>> y = np.sin(x)
>>>
>>> fig, ax = fr.subplots()
>>> ax.plot(x, y, color='red', linewidth=2, id='sine_wave')
>>> ax.set_xlabel('Time')
>>> ax.set_ylabel('Amplitude')
>>> fr.save(fig, 'my_figure.yaml')
Reproducing a figure:
>>> fig, ax = fr.reproduce('my_figure.yaml')
>>> plt.show()
Notes
Submodules:
fr.utils: Unit conversions, font checks, low-level recipe accessfr.styles: Axis helpers, spine management, plot styling functionsfr.viz: Diagram and graph visualization utilities
>>> from figrecipe import utils
>>> utils.mm_to_inch(25.4) # Unit conversions
>>> from figrecipe import styles
>>> styles.hide_spines(ax) # Spine management
- figrecipe.subplots(nrows=1, ncols=1, axes_width_mm=None, axes_height_mm=None, margin_left_mm=None, margin_right_mm=None, margin_bottom_mm=None, margin_top_mm=None, space_w_mm=None, space_h_mm=None, style=None, apply_style_mm=True, panel_labels=None, **kwargs)[source]
Create a figure with recording-enabled axes.
This is a drop-in replacement for plt.subplots() that wraps the returned figure and axes with recording capabilities.
Supports mm-based layout control for publication-quality figures.
- Parameters:
nrows (int) – Number of rows and columns of subplots.
ncols (int) – Number of rows and columns of subplots.
axes_width_mm (float, optional) – Axes dimensions in mm.
axes_height_mm (float, optional) – Axes dimensions in mm.
margin_left_mm (float, optional) – Left/right margins in mm.
margin_right_mm (float, optional) – Left/right margins in mm.
margin_bottom_mm (float, optional) – Bottom/top margins in mm.
margin_top_mm (float, optional) – Bottom/top margins in mm.
space_w_mm (float, optional) – Horizontal/vertical spacing between axes in mm.
space_h_mm (float, optional) – Horizontal/vertical spacing between axes in mm.
style (dict, optional) – Style configuration dictionary.
apply_style_mm (bool) – If True (default), apply loaded style to axes.
panel_labels (bool or None) – If True, add panel labels (A, B, C, …).
**kwargs – Additional arguments passed to plt.subplots().
- Return type:
Tuple[RecordingFigure,Union[RecordingAxes,ndarray[tuple[Any,...],dtype[TypeVar(_ScalarT, bound=generic)]]]]- Returns:
fig (RecordingFigure) – Wrapped figure object.
axes (RecordingAxes or ndarray) – Wrapped axes.
- figrecipe.save(fig, path, save_recipe=True, include_data=True, data_format='csv', csv_format='separate', validate=True, validate_mse_threshold=100.0, validate_error_level='error', validate_axis_range_alignment=True, validate_axis_range_alignment_error_level='warning', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=False, save_editable=False)[source]
Save a figure as image and recipe. Unified API with fig.savefig().
- Parameters:
fig (RecordingFigure or Figure) – The figure to save.
path (str or Path) – Output path (.png, .pdf, .svg, .yaml, etc.)
save_recipe (bool) – If True (default), save YAML recipe alongside the image.
include_data (bool) – If True (default), save large arrays to separate files.
data_format (str) – Format for data files: ‘csv’, ‘npz’, or ‘inline’.
csv_format (str) – CSV structure: ‘separate’ (default) or ‘single’ (scitex-compatible).
validate (bool) – If True (default), validate reproducibility after saving.
validate_mse_threshold (float) – Maximum acceptable MSE for validation (default: 100).
validate_error_level (str) – How to handle failures: ‘error’, ‘warning’, or ‘debug’.
validate_axis_range_alignment (bool) – If True (default), run the runtime
axis_range_alignmentcheck on the rendered figure. Catches the autoscale-with- different-data case that the static STX-FIG001 lint misses.validate_axis_range_alignment_error_level (str) – Dispatch level for the axis-range-alignment check: ‘warning’ (default), ‘error’, or ‘debug’ (silent).
verbose (bool) – If True (default), print save status.
dpi (int, optional) – DPI for image output.
image_format (str, optional) – Image format when path is YAML.
facecolor (str, optional) – Background color. When opaque, patches are made visible.
save_hitmap (bool) – If True (default), save hitmap image for GUI editor element selection.
save_editable (bool) – If True, write the editable-figure JSON (schema
scitex.plt.figure.editable) to<stem>.jsonnext to the image. Default False — opt in for the GUI / web editor.
- Returns:
If save_recipe=True: (image_path, yaml_path, ValidationResult or None) If save_recipe=False: (image_path, None, None)
- Return type:
- figrecipe.reproduce(path, calls=None, skip_decorations=False, apply_style=True)[source]
Reproduce a figure from a recipe file or bundle.
- Parameters:
path (str or Path) – Path to recipe. Supports multiple formats: - .yaml/.yml file: Direct recipe file - .png/.jpg/etc: Image with associated .yaml - Directory: Bundle containing recipe.yaml - .zip: ZIP bundle (both old recipe.yaml format and new spec.json format)
calls (list of str, optional) – If provided, only reproduce these specific call IDs.
skip_decorations (bool) – If True, skip decoration calls.
apply_style (bool) – If True (default), apply saved style.
- Return type:
- Returns:
fig (matplotlib.figure.Figure) – Reproduced figure.
axes (Axes or list of Axes) – Reproduced axes.
- figrecipe.load(path, calls=None, skip_decorations=False, apply_style=True)
Reproduce a figure from a recipe file or bundle.
- Parameters:
path (str or Path) – Path to recipe. Supports multiple formats: - .yaml/.yml file: Direct recipe file - .png/.jpg/etc: Image with associated .yaml - Directory: Bundle containing recipe.yaml - .zip: ZIP bundle (both old recipe.yaml format and new spec.json format)
calls (list of str, optional) – If provided, only reproduce these specific call IDs.
skip_decorations (bool) – If True, skip decoration calls.
apply_style (bool) – If True (default), apply saved style.
- Return type:
- Returns:
fig (matplotlib.figure.Figure) – Reproduced figure.
axes (Axes or list of Axes) – Reproduced axes.
- figrecipe.compose(sources, layout=None, canvas_size_mm=None, width_mm=None, gap_mm=2.0, dpi=300, panel_labels=False, label_style='uppercase', caption=None, panel_captions=None, **kwargs)[source]
Compose a new figure from multiple sources (recipes or raw images).
Supports three modes automatically detected from sources/layout format:
Grid-based: sources={(row, col): path} Uses layout=(nrows, ncols) for subplot grid.
Mm-based: sources={path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} Uses canvas_size_mm for precise positioning.
Tiled (row-justified, whitespace-free): layout=[[“A”,”B”,”C”],[“D”]] (or the multiline string “A B CnD”) with sources={“A”: path, …}. Each panel keeps its true aspect ratio; within a row all panels share one common height and sit edge-to-edge (only
gap_mmbetween) so there is no whitespace, and every row spans the same width so the right edge is never ragged. The first layout row is rendered on top.
- Parameters:
sources (dict) – One of: - Grid-based: {(row, col): source_path} mapping positions to sources - Mm-based: {source_path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} - Tiled: {label: source} keyed by the string labels used in
layoutlayout (tuple, str, or list of list of str, optional) –
(nrows, ncols) for grid-based composition (auto-detected if omitted).
list of rows of labels (
[["A","B"],["C"]]) or a multiline string ("A B\nC") for tiled composition.
canvas_size_mm (tuple, optional) – (width_mm, height_mm) for mm-based composition. Required for mm-based mode.
width_mm (float, optional) – Overall content width (mm) for TILED composition. When omitted the default width is the widest row at its true content size, i.e.
max over rows of (sum of true panel widths + (k-1)*gap_mm). Ignored by grid/mm modes.gap_mm (float) – Gap between panels in mm (gutter; tiled mode uses it as the edge-to-edge spacing, and
gap_mm=0makes panels share edges exactly).dpi (int) – DPI for the output figure.
panel_labels (bool) – If True, add panel labels (A, B, C…) to each panel.
label_style (str) – ‘uppercase’, ‘lowercase’, or ‘numeric’.
caption (str, optional) – Figure-level caption text. Rendered on the figure and persisted in the recipe so it survives save→reproduce.
panel_captions (list of str, optional) – Per-panel caption texts. When provided, panel labels (A, B, C…) are placed with the corresponding caption text on each panel.
**kwargs – Additional arguments passed to figure creation.
- Return type:
Tuple[RecordingFigure,Union[RecordingAxes,ndarray[tuple[Any,...],dtype[TypeVar(_ScalarT, bound=generic)]],List[RecordingAxes]]]- Returns:
fig (RecordingFigure) – Composed figure (editable, recordable).
axes (RecordingAxes, ndarray, or list) – Axes of the composed figure.
Examples
Grid-based composition:
>>> fig, axes = fr.compose( ... layout=(1, 2), ... sources={ ... (0, 0): "panel_a.yaml", ... (0, 1): "panel_b.yaml", ... } ... )
Composition with figure-level caption:
>>> fig, axes = fr.compose( ... layout=(2, 2), ... sources={ ... (0, 0): "a.yaml", (0, 1): "b.yaml", ... (1, 0): "c.yaml", (1, 1): "d.yaml", ... }, ... caption="Figure 1. Four-condition comparison (n=3).", ... )
Mm-based free-form composition:
>>> fig, axes = fr.compose( ... canvas_size_mm=(180, 120), ... sources={ ... "panel_a.yaml": {"xy_mm": (0, 0), "size_mm": (85, 55)}, ... "panel_b.yaml": {"xy_mm": (90, 0), "size_mm": (85, 55)}, ... "panel_c.yaml": {"xy_mm": (0, 60), "size_mm": (175, 55)}, ... } ... )
Tiled (row-justified, whitespace-free) composition:
>>> fig, axes = fr.compose( ... layout=[["A", "B", "C"], ["D"]], ... sources={"A": "a.yaml", "B": "b.yaml", ... "C": "c.yaml", "D": "d.yaml"}, ... width_mm=180, gap_mm=1.0, ... )
- figrecipe.align_panels(fig, panels, mode, reference=None)[source]
Align multiple panels to a reference panel.
- Parameters:
fig (RecordingFigure) – The figure containing the panels.
panels (list of tuple) – List of (row, col) positions to align.
mode (str or AlignmentMode) – Alignment mode: ‘left’, ‘right’, ‘top’, ‘bottom’, ‘center_h’, ‘center_v’, ‘axis_x’, ‘axis_y’.
reference (tuple, optional) – Reference panel position. If None, uses first panel.
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # Align left column panels to left edge >>> fr.align_panels(fig, [(0, 0), (1, 0)], mode="left")
- figrecipe.distribute_panels(fig, panels, direction='horizontal', spacing_mm=None)[source]
Distribute panels evenly with optional fixed spacing.
- Parameters:
fig (RecordingFigure) – The figure containing the panels.
panels (list of tuple) – List of (row, col) positions to distribute.
direction (str) – ‘horizontal’ or ‘vertical’.
spacing_mm (float, optional) – Fixed spacing in mm. If None, distribute evenly within current bounds.
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(1, 3) >>> # Distribute evenly >>> fr.distribute_panels(fig, [(0, 0), (0, 1), (0, 2)]) >>> # With fixed 5mm spacing >>> fr.distribute_panels(fig, [(0, 0), (0, 1), (0, 2)], spacing_mm=5)
- figrecipe.align_smart(fig, panels=None)[source]
Automatically align panels in a compact grid layout.
Works like human behavior: 1. Detect grid structure (nrows, ncols) 2. Place panels from top-left to bottom-right 3. Calculate minimum rectangle to cover all content in each row/column 4. Unify row heights and column widths 5. Use space effectively with theme margins and spacing
Uses margin and spacing values from the loaded SCITEX theme: - margins.left_mm, margins.right_mm, margins.top_mm, margins.bottom_mm - spacing.horizontal_mm, spacing.vertical_mm
- Parameters:
fig (RecordingFigure) – The figure containing the panels.
panels (list of tuple, optional) – Specific panels to align. If None, aligns all panels.
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # ... add plots ... >>> fr.align_smart(fig) # Align all panels using theme settings
- figrecipe.gui(source=None, style=None, port=5050, host='127.0.0.1', open_browser=True, hot_reload=False, working_dir=None, desktop=False)[source]
Launch interactive GUI editor for figure styling.
- Parameters:
source (RecordingFigure, str, Path, or None) – Either a live RecordingFigure object, path to a .yaml recipe file, or None to create a new blank figure.
style (str or dict, optional) – Style preset name or style dict.
port (int, optional) – Django server port (default: 5050).
host (str, optional) – Host to bind server (default: “127.0.0.1”, use “0.0.0.0” for Docker).
open_browser (bool, optional) – Whether to open browser automatically (default: True).
hot_reload (bool, optional) – Enable hot reload (default: False).
working_dir (str or Path, optional) – Working directory for file browser (default: directory containing source).
desktop (bool, optional) – Launch as native desktop window using pywebview (default: False). Requires: pip install figrecipe[desktop]
- Returns:
Final style overrides after editing session.
- Return type:
- figrecipe.crop(input_path, output_path=None, margin_mm=1.0, margin_px=None, overwrite=False, verbose=False, return_offset=False)[source]
Crop a figure image to its content area with a specified margin.
- Parameters:
input_path (str or Path) – Path to the input image.
output_path (str or Path, optional) – Path to save the cropped image.
margin_mm (float, optional) – Margin in millimeters (default: 1.0mm).
margin_px (int, optional) – Margin in pixels (overrides margin_mm if provided).
overwrite (bool, optional) – Whether to overwrite the input file (default: False)
verbose (bool, optional) – Whether to print detailed information (default: False)
return_offset (bool, optional) – If True, also return crop offset info dict (default: False)
- Returns:
Path to the saved cropped image. If return_offset=True, returns (path, offset_dict).
- Return type:
Path or tuple
- figrecipe.validate(path, mse_threshold=100.0)[source]
Validate that a saved recipe can reproduce its original figure.
- figrecipe.extract_data(path)[source]
Extract data arrays from a saved recipe.
- Returns:
Nested dictionary: {call_id: {‘x’: array, ‘y’: array, …}}
- Return type:
- figrecipe.add_qr_to_figure(fig, metadata, position='bottom-right', size=0.08)[source]
Add a minimal QR code to a matplotlib figure.
- Parameters:
fig (matplotlib.figure.Figure) – Target figure to overlay onto.
metadata (dict) – Payload to encode. If
"url"is absent,"https://scitex.ai"is added so the QR resolves to something even when consumers don’t provide one.position (str) – One of
"bottom-right","bottom-left","top-right","top-left". Unknown values fall back to"bottom-right".size (float) – Relative size of the QR overlay (fraction of figure width).
- Returns:
The same figure, with a QR overlay axes added. If the optional
qrcode/Pillowdependencies are not installed, the figure is returned unmodified and a warning is logged.- Return type:
- figrecipe.add_figure_caption(fig, caption, *, figure_label=None, style='scientific', position='bottom', width_ratio=0.9, font_size='small', wrap_width=80, save_to_file=False, file_path=None)[source]
Add a figure caption.
The caption text is stripped of Markdown formatting (bold/italic) so it renders cleanly in matplotlib. The caption is also recorded on
fig.record.captionso it survives save→reproduce round-trip.- Parameters:
fig (matplotlib.figure.Figure or RecordingFigure) – The figure to add caption to.
caption (str) – The caption text (Markdown formatting is automatically stripped).
figure_label (str, optional) – Custom figure label (e.g. “Figure 1”). Auto-generated if None.
style (str) – Caption style: “scientific”, “nature”, “ieee”, “apa”.
position (str) – Caption position: “bottom” (default) or “top”.
width_ratio (float) – Width of caption relative to figure width.
wrap_width (int) – Character width for text wrapping.
save_to_file (bool) – Whether to also save caption to a separate file.
file_path (str, optional) – Path for caption file.
- Returns:
The rendered caption text (Markdown-stripped).
- Return type:
- figrecipe.add_panel_captions(fig, axes, panel_captions, *, main_caption='', figure_label=None, panel_style='letter_bold', position='top_left', font_size='medium', offset=(0.02, 0.98))[source]
Add panel captions (A, B, C, etc.) to subplot panels.
Panel labels are rendered with Markdown-stripped text so they display cleanly in matplotlib.
- Parameters:
fig (matplotlib.figure.Figure or RecordingFigure) – The figure containing panels.
axes (Axes, list, or ndarray) – Axes objects for each panel.
panel_captions (list or dict) – Caption text for each panel.
main_caption (str) – Main figure caption (optional, auto-attached).
figure_label (str, optional) – Figure label for the main caption.
panel_style (str) – Panel label style: “letter_bold”, “letter_italic”, “number”.
position (str) – Panel label position: “top_left”, “top_right”, etc.
offset (tuple) – Position offset for panel labels.
- Returns:
Dictionary mapping panel labels to full caption text.
- Return type:
- figrecipe.set_manuscript_mode(on=True)[source]
Enable/disable manuscript mode process-wide.
- Return type:
- figrecipe.manuscript_mode(on=True)[source]
Context manager that sets manuscript mode for the enclosed block.
- figrecipe.is_manuscript_mode()[source]
True when manuscript mode is active (explicit flag OR env var).
- Return type:
- figrecipe.panel_label(ax, label, loc='upper left', offset=(-0.1, 1.05), fontsize=10, fontweight='bold', text_color='black', **kwargs)[source]
Place a single panel label (A, B, C, etc.) on one axes.
- Parameters:
ax (matplotlib.axes.Axes) – The axes to annotate.
label (str) – The panel label text (e.g. ‘A’, ‘B’, ‘(1)’).
loc (str) – Location hint: ‘upper left’ (default), ‘upper right’, ‘lower left’, ‘lower right’.
offset (tuple of float) – (x, y) offset in axes coordinates. Default (-0.1, 1.05).
fontsize (float) – Font size in points (default 10).
fontweight (str) – Font weight (default ‘bold’).
text_color (str) – Text color (default ‘black’).
**kwargs – Additional arguments passed to
ax.text().
- Returns:
The created text annotation.
- Return type:
- class figrecipe.Figz(path)[source]
Bases:
objectMulti-panel figure bundle (.fig.zip).
- Manages a ZIP file containing:
manifest.json - bundle type declaration spec.json - figure spec with panel list style.json - figure dimensions and theme panels/ - .plt.zip panel bundles
Example
>>> figz = Figz.create("Figure1.fig.zip", "Figure1") >>> figz.add_panel("A", pltz_path) >>> figz.add_panel("B", pltz_bytes)
- add_panel(label, pltz_source, position=None, size=None)[source]
Add a .plt.zip panel to this figure.
- add_panel_from_png(label, png_bytes, plot_type='image', position=None, size=None, hitmap_bytes=None, hitmap_color_map=None, data_csv=None)[source]
Create a .plt.zip bundle from PNG bytes and embed it as a panel.
Convenience wrapper around
add_panel()for the common case of adding a pre-rendered PNG image as a panel.- Parameters:
label (str) – Panel label (e.g., “A”, “B”).
png_bytes (bytes) – PNG image data.
plot_type (str, optional) – Plot type label stored in the panel’s spec.json (default: “image”).
position (dict, optional) – Panel position e.g. {“x_mm”: 5, “y_mm”: 5}.
size (dict, optional) – Panel size e.g. {“width_mm”: 80, “height_mm”: 68}.
- Return type:
- get_panel(label)[source]
Extract panel as Pltz instance (via temp file).
Note: The caller is responsible for cleaning up the temp file (accessible via the returned Pltz instance’s .path attribute).
- class figrecipe.Pltz(path)[source]
Bases:
objectSingle-plot bundle (.plt.zip).
Thin wrapper around figrecipe’s existing bundle functions: - load_bundle() - save_bundle() - reproduce_bundle()
Bundle structure (inside ZIP):
{stem}/ spec.json # WHAT to plot (semantic specification) style.json # HOW it looks (appearance settings) data.csv # Raw data recipe.yaml # Reproducible recipe exports/ figure.png
- classmethod from_png(png_bytes, path, plot_type='image', spec=None, style=None, hitmap_bytes=None, hitmap_color_map=None, data_csv=None)[source]
Create a .plt.zip bundle wrapping a pre-rendered PNG image.
Useful when a figure is rendered externally (e.g., from a gallery template) and needs to be stored as a figrecipe bundle.
- Parameters:
- Returns:
Loaded Pltz instance wrapping the saved bundle.
- Return type:
- classmethod create(path, fig)[source]
Save a RecordingFigure as a .plt.zip bundle.
- Parameters:
path (str or Path) – Output path. If it doesn’t end in .zip, .zip is appended.
fig (RecordingFigure) – Figure created with figrecipe.subplots().
- Returns:
Loaded Pltz instance wrapping the saved bundle.
- Return type:
- get_preview()[source]
Read pre-rendered preview PNG from bundle.
- Returns:
PNG bytes, or None if no preview image is stored.
- Return type:
bytes or None
- render_preview()[source]
Reproduce figure and render to PNG bytes.
- Returns:
PNG bytes, or None on failure.
- Return type:
bytes or None
- figrecipe.save_bundle(fig, path, dpi=None, image_formats=None, save_hitmap=False, verbose=True)[source]
Save figure as a layered bundle (ZIP format).
Bundle structure inside ZIP:
spec.json # WHAT (semantic specification) style.json # HOW (appearance settings) data.csv # DATA (immutable source data) recipe.yaml # Reproducible recipe (for fr.reproduce()) exports/ figure.png figure_hitmap.png # only if save_hitmap=True
- Parameters:
fig (RecordingFigure) – The figure to save.
path (str or Path) – Output path (.zip will be added if not present).
dpi (int, optional) – DPI for exports (default from style or 300).
image_formats (list, optional) – Image formats to export (default: [‘png’]).
save_hitmap (bool) – Whether to save the per-pixel hitmap PNG used by the GUI editor for diff visualisation (default: False). Hitmap rendering is expensive and the typical save() caller doesn’t need it; opt in with save_hitmap=True when persisting bundles for the editor.
verbose (bool) – Whether to print status (default: True).
- Returns:
Path to saved ZIP bundle.
- Return type:
Path
- figrecipe.load_style(style='SCITEX', dark=False, background=None)[source]
Load style configuration and apply it globally.
After calling this function, subsequent subplots() calls will automatically use the loaded style (fonts, colors, theme, etc.).
- Parameters:
style (str, Path, bool, or None) – One of: - “SCITEX” / “FIGRECIPE”: Scientific publication style (default) - “MATPLOTLIB”: Vanilla matplotlib defaults - Path to custom YAML file: “/path/to/my_style.yaml” - None or False: Unload style (reset to matplotlib defaults)
dark (bool, optional) – If True, apply dark theme transformation (default: False). Equivalent to appending “_DARK” to preset name.
background (str, optional) – Override default background color. E.g., ‘white’ for opaque figures. Sets theme.light.figure_bg and theme.light.axes_bg. Use ‘transparent’ for transparent background.
- Returns:
Style configuration with dot-notation access. Returns None if style is unloaded.
- Return type:
DotDict or None
Examples
>>> import figrecipe as fr
>>> # Load scientific style (default) >>> fr.load_style() >>> fr.load_style("SCITEX") # explicit
>>> # Load with white background (override transparent default) >>> fr.load_style("SCITEX", background='white')
>>> # Load dark theme >>> fr.load_style("SCITEX_DARK") >>> fr.load_style("SCITEX", dark=True) # equivalent
>>> # Reset to vanilla matplotlib >>> fr.load_style(None) # unload >>> fr.load_style(False) # unload >>> fr.load_style("MATPLOTLIB") # explicit vanilla
>>> # Access style values >>> style = fr.load_style("SCITEX") >>> style.axes.width_mm 40
- figrecipe.unload_style()[source]
Unload the current style and reset to matplotlib defaults.
After calling this, subsequent subplots() calls will use vanilla matplotlib behavior without FigRecipe styling.
Examples
>>> import figrecipe as fr >>> fr.load_style("SCITEX") # Apply scientific style >>> fig, ax = fr.subplots() # Styled >>> fr.unload_style() # Reset to matplotlib defaults >>> fig, ax = fr.subplots() # Vanilla matplotlib
- figrecipe.list_presets()[source]
List available style presets.
Examples
>>> import figrecipe as ps >>> ps.list_presets() ['MINIMAL', 'PRESENTATION', 'SCIENTIFIC']
- class figrecipe.Diagram(title=None, width_mm=170.0, height_mm=120.0, padding_mm=10.0, gap_mm=None)[source]
Bases:
objectBuilder for rich box-and-arrow diagrams with mm-based coordinates.
- add_box(id, title, subtitle=None, content=None, emphasis='normal', shape='rounded', x_mm=None, y_mm=None, width_mm=None, height_mm=None, fill_color=None, border_color=None, title_color=None, padding_mm=5.0, margin_mm=0.0, node_class=None, state=None, language=None, bullet=None)[source]
Add a rich text box. See BoxSpec for node_class/state/language/bullet.
- Return type:
- add_container(id, title=None, children=None, emphasis='muted', x_mm=None, y_mm=None, width_mm=None, height_mm=None, fill_color=None, border_color=None, title_loc='upper center', direction='row', container_gap_mm=8.0, container_padding_mm=8.0, equalize_heights=True, equalize_widths=True)[source]
Add a container. equalize_heights/widths: match children in row/column.
- Return type:
- add_arrow(source, target, source_anchor='auto', target_anchor='auto', source_dx=0.0, source_dy=0.0, target_dx=0.0, target_dy=0.0, label=None, style='solid', color=None, curve=0.0, linewidth_mm=0.5, label_offset_mm=None, margin_mm=None)[source]
Add an arrow connecting two boxes.
- Return type:
- add_icon(id, source, x_mm, y_mm, width_mm=8.0, height_mm=8.0, color=None, opacity=1.0)[source]
Add an icon (SVG/PNG or built-in: warning/check/cross/info/lock).
- Return type:
- validate_containers()[source]
Check every container fully encloses its declared children.
- Return type:
- auto_layout(layout='lr', margin_mm=15.0, box_size_mm=None, gap_mm=10.0, avoid_overlap=True, justify='space-between', align_items='center')[source]
Automatically position boxes. See _layout for details.
- Return type:
- _auto_box_height(box)[source]
Compute box height from content when height_mm is not specified.
- Return type:
- _finalize_canvas_size()[source]
Compute canvas height from element positions when height_mm=None.
- Return type:
- render(ax=None, auto_fix=False, auto_curve=True)[source]
Render. auto_fix=True resolves violations; auto_curve=False skips R7.
- save(path, dpi=200, save_recipe=True, save_hitmap=False, save_debug=True, watermark=False)[source]
Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.
- Return type:
- render_to_file(path, dpi=200, save_recipe=True, save_hitmap=False, save_debug=True, watermark=False)
Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.
- Return type:
- figrecipe.build_spec(params)[source]
Convert a parameter dict to a figrecipe spec dict.
- Parameters:
params (dict) – Flat parameter dict. Required key:
kind. For XY plots:x,y(comma-separated floats or strings). For distributions:data,data2..data6,labels. For pie:data,labels. For heatmap:data,nrows,ncols. Optional:color,title,xlabel,ylabel,width,height,yerr.- Returns:
Figrecipe-compatible spec.
- Return type:
- Raises:
ValueError – If required parameters are missing or kind is unsupported.
- figrecipe.build_spec_from_csv(csv_path, params)[source]
Build a figrecipe spec from a CSV file path and parameters.
Uses figrecipe’s native
data_file+ column name resolution.- Parameters:
- Returns:
Figrecipe-compatible spec.
- Return type:
- Raises:
ValueError – If required parameters are missing or kind is unsupported.
- figrecipe.render_spec_to_bytes(spec, *, dpi=300, fmt='png', facecolor='white')[source]
Render a figrecipe spec dict to image bytes.
- Parameters:
- Returns:
Encoded image bytes.
- Return type:
- figrecipe.termplot(*args)[source]
Plot y (and optional x) values in the terminal using termplotlib.
- Parameters:
*args – Either
(y,)— plotted against its indices — or(x, y, ...)where extra positional arguments are ignored.- Returns:
Displays the plot in the terminal.
- Return type:
None
- figrecipe.draw_graph(ax, G, *, layout='spring', pos=None, seed=42, node_size=100, node_color='#3498db', node_alpha=0.8, node_shape='o', node_edgecolors='white', node_linewidths=0.34, edge_width=0.34, edge_color='gray', edge_alpha=0.5, edge_style='solid', arrows=None, arrowsize=10, arrowstyle='-|>', connectionstyle='arc3,rad=0.0', labels=False, font_size=6, font_color='black', font_weight='normal', font_family='sans-serif', colormap='viridis', vmin=None, vmax=None, **layout_kwargs)[source]
Draw a NetworkX graph on matplotlib axes.
- Parameters:
ax (matplotlib.axes.Axes) – The axes to draw on.
G (networkx.Graph) – The graph to draw.
layout (str) – Layout algorithm: ‘spring’, ‘circular’, ‘kamada_kawai’, ‘shell’, ‘spectral’, ‘random’, ‘planar’, ‘spiral’, ‘hierarchical’.
pos (dict, optional) – Pre-computed node positions {node: (x, y)}.
seed (int) – Random seed for layout reproducibility.
node_size (str, callable, or float) – Node sizes. Can be attribute name, callable (node, data) -> size, or scalar.
node_color (str, callable, or any) – Node colors. Can be attribute name, callable, color name, or array.
node_alpha (float) – Node transparency.
node_shape (str) – Node marker shape.
edge_width (str, callable, or float) – Edge widths. Can be attribute name, callable (u, v, data) -> width, or scalar.
edge_color (str, callable, or any) – Edge colors.
edge_alpha (float) – Edge transparency.
arrows (bool, optional) – Draw arrows for directed graphs. Auto-detected if None.
arrowsize (float) – Arrow head size for directed edges.
labels (bool, dict, or str) – Node labels. True for node IDs, dict for custom labels, str for attribute name.
font_size (float) – Label font size (default 6pt for scitex).
colormap (str) – Matplotlib colormap for numeric node colors.
**layout_kwargs – Additional kwargs passed to layout algorithm.
- Returns:
Dictionary with ‘pos’, ‘node_collection’, ‘edge_collection’.
- Return type:
- figrecipe.smart_align(fig, panels=None)
Automatically align panels in a compact grid layout.
Works like human behavior: 1. Detect grid structure (nrows, ncols) 2. Place panels from top-left to bottom-right 3. Calculate minimum rectangle to cover all content in each row/column 4. Unify row heights and column widths 5. Use space effectively with theme margins and spacing
Uses margin and spacing values from the loaded SCITEX theme: - margins.left_mm, margins.right_mm, margins.top_mm, margins.bottom_mm - spacing.horizontal_mm, spacing.vertical_mm
- Parameters:
fig (RecordingFigure) – The figure containing the panels.
panels (list of tuple, optional) – Specific panels to align. If None, aligns all panels.
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # ... add plots ... >>> fr.align_smart(fig) # Align all panels using theme settings
- figrecipe.edit(source=None, style=None, port=5050, host='127.0.0.1', open_browser=True, hot_reload=False, working_dir=None, desktop=False)
Launch interactive GUI editor for figure styling.
- Parameters:
source (RecordingFigure, str, Path, or None) – Either a live RecordingFigure object, path to a .yaml recipe file, or None to create a new blank figure.
style (str or dict, optional) – Style preset name or style dict.
port (int, optional) – Django server port (default: 5050).
host (str, optional) – Host to bind server (default: “127.0.0.1”, use “0.0.0.0” for Docker).
open_browser (bool, optional) – Whether to open browser automatically (default: True).
hot_reload (bool, optional) – Enable hot reload (default: False).
working_dir (str or Path, optional) – Working directory for file browser (default: directory containing source).
desktop (bool, optional) – Launch as native desktop window using pywebview (default: False). Requires: pip install figrecipe[desktop]
- Returns:
Final style overrides after editing session.
- Return type:
- figrecipe.export_editable(fig, title='', description='', include_full_paths=False, simplify_threshold=0.5)
Export a matplotlib figure with geometry data for interactive editing.
This produces a Schema v0.3 compliant dictionary with axes-local pixel coordinates for all visual elements, suitable for shape-based hit testing.
- Parameters:
fig (matplotlib.figure.Figure or scitex.plt.FigureWrapper) – The figure to export
title (str) – Optional title for the figure metadata
description (str) – Optional description for the figure metadata
include_full_paths (bool) – If True, include full (unsimplified) paths for lines. Default False.
simplify_threshold (float) – Maximum pixel error for path simplification. Default 0.5.
- Returns:
Schema v0.3 compliant dictionary with structure: - scitex_schema: “scitex.plt.figure.editable” - scitex_schema_version: “0.3.0” - figure: {size_px, dpi, …} - axes: {ax_id: {bbox_px, …}, …} - elements: {elem_id: {geometry_px, style, …}, …} - statistics: {} (placeholder for stats integration) - data: {} (placeholder for linked data) - output: {} (rendering metadata)
- Return type:
- figrecipe.enable_svg()[source]
Manually enable SVG format for Jupyter notebook display.
Call this if figures appear pixelated in notebooks.
Examples
>>> import figrecipe as fr >>> fr.enable_svg() # Enable SVG rendering >>> fig, ax = fr.subplots() # Now renders as crisp SVG
- figrecipe.apply_style(ax, style=None)[source]
Apply mm-based styling to an axes.
- Parameters:
ax (matplotlib.axes.Axes) – Target axes to apply styling to.
style (dict or DotDict, optional) – Style configuration. If None, uses default FIGRECIPE_STYLE.
- Returns:
Trace line width in points.
- Return type:
Examples
>>> import figrecipe as ps >>> import matplotlib.pyplot as plt >>> fig, ax = plt.subplots() >>> trace_lw = ps.apply_style(ax) >>> ax.plot(x, y, lw=trace_lw)
- figrecipe.signature(image_path=None, recipe_path=None)[source]
Compute verification signature for a saved figure.
- figrecipe.caption_with_signature(caption, image_path=None, recipe_path=None, style='short')[source]
Append verification signature to a figure caption.
- Parameters:
- Returns:
Caption with appended signature.
- Return type:
Recording Wrappers (internal)
These classes back the public subplots() return value. They live
under figrecipe._wrappers rather than the top-level namespace, so
they’re documented here separately.
- class figrecipe._wrappers.RecordingFigure(fig, recorder, axes)[source]
Bases:
FigureTextMixinWrapper around matplotlib Figure that manages recording.
- Parameters:
fig (matplotlib.figure.Figure) – The underlying matplotlib figure.
recorder (Recorder) – The recorder instance.
axes (list of RecordingAxes) – Wrapped axes objects.
Examples
>>> import figrecipe as ps >>> fig, ax = ps.subplots() >>> ax.plot([1, 2, 3], [4, 5, 6]) >>> ps.save(fig, "my_figure.yaml")
- _on_draw_finalize(event)[source]
Apply figrecipe finalize hooks once per figure lifetime.
Run-once: setting a new locator marks the canvas stale, which on the inline notebook backend triggers another draw and a SECOND inline render of the same figure. We only need to finalize once per figure — cache the flag and short-circuit on subsequent draws.
Re-entrancy guard: finalize_ticks may swap a locator, which on some backends triggers another draw and would recurse. The flag breaks the loop.
- property axes: List[List[RecordingAxes]]
Get axes as 2D array.
- property dpi
Proxy dpi to underlying figure.
Needed as a class-level descriptor so matplotlib’s _setattr_cm can do getattr(type(obj), ‘dpi’) during savefig/print_figure.
- draw(renderer)[source]
Proxy draw to underlying figure.
Needed as a class-level method so matplotlib’s _setattr_cm can do getattr(type(obj), ‘draw’) during _get_renderer.
- property flat: List[RecordingAxes]
Get flattened list of all axes.
- property record: FigureRecord
Get the figure record.
- _get_theme_text_color(default='black')[source]
Get text color from loaded style’s theme settings.
- Return type:
- colorbar(mappable, ax=None, **kwargs)[source]
Add a colorbar and record it for reproduction.
axmay be a single axes OR a list/array of axes (a shared colorbar that steals space from several panels, e.g.fig.colorbar(im, ax=axes.ravel().tolist())). An explicitcax=<axes>(the colorbar is drawn into a caller-provided axes) and a standaloneScalarMappableare also handled. Every source axes is recorded inax_keys; the colorbar’s resolved geometry is captured later at SAVE time (see_capture_colorbar_geometry) so reproduction can pin it exactly. Recording logic lives in_figure_colorbarto keep this module within the per-file line budget.- Return type:
- add_panel_labels(labels=None, loc='upper left', offset=(-0.1, 1.05), fontsize=None, fontweight='bold', **kwargs)[source]
Add panel labels (A, B, C, D, etc.) to multi-panel figures.
- Parameters:
labels (list of str, optional) – Custom labels. If None, uses uppercase letters (A, B, C, …).
loc (str) – Location hint: ‘upper left’ (default), ‘upper right’, ‘lower left’, ‘lower right’.
offset (tuple of float) – (x, y) offset in axes coordinates from the corner. Default is (-0.1, 1.05) for upper left positioning.
fontsize (float, optional) – Font size in points. If None, uses style’s title_pt or 10.
fontweight (str) – Font weight (default: ‘bold’).
**kwargs – Additional arguments passed to ax.text().
- Returns:
The matplotlib Text objects created.
- Return type:
list of Text
Examples
>>> fig, axes = fr.subplots(2, 2) >>> fig.add_panel_labels() # Adds A, B, C, D >>> fig.add_panel_labels(['i', 'ii', 'iii', 'iv']) # Custom labels >>> fig.add_panel_labels(loc='upper right', offset=(1.05, 1.05))
- set_title_metadata(title)[source]
Set figure title metadata (not rendered, stored in recipe).
This is for storing a publication/reference title for the figure, separate from suptitle which is rendered on the figure.
- Parameters:
title (str) – The figure title for publication/reference.
- Returns:
Self for method chaining.
- Return type:
Examples
>>> fig, ax = fr.subplots() >>> fig.set_title_metadata("Effect of temperature on reaction rate") >>> fig.set_caption("Figure 1. Reaction rates measured at various temperatures.")
- set_caption(caption)[source]
Set figure caption metadata (not rendered, stored in recipe).
This is for storing a publication caption for the figure, typically used in scientific papers (e.g., “Fig. 1. Description…”).
- Parameters:
caption (str) – The figure caption text.
- Returns:
Self for method chaining.
- Return type:
Examples
>>> fig, ax = fr.subplots() >>> fig.set_caption("Figure 1. Temperature dependence of reaction rates.")
- set_stats(stats)[source]
Set figure-level statistics metadata (not rendered, stored in recipe).
- Parameters:
stats (dict) – Statistics dictionary (comparisons, summary, correction_method, alpha).
- Return type:
- generate_caption(style='publication', template=None)[source]
Generate caption from stored stats. Styles: publication, brief, detailed.
- Return type:
- savefig(fname, save_recipe=True, include_data=True, data_format='csv', csv_format='separate', validate=True, validate_mse_threshold=100.0, validate_error_level='error', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=False, **kwargs)[source]
Save figure — equivalent to fr.save(). Same DPI, crop, recipe.
Returns (image_path, yaml_path, result).
**kwargspassed to matplotlib savefig for file-like objects.
- class figrecipe._wrappers.RecordingAxes(ax, recorder, position=(0, 0))[source]
Bases:
RecordingAxesMethods,AxesStyleMixin,SciTexMixin,DiagramMixinWrapper around matplotlib Axes that records all calls.
This wrapper intercepts calls to plotting methods and records them for later reproduction.
- Parameters:
ax (matplotlib.axes.Axes) – The underlying matplotlib axes.
recorder (Recorder) – The recorder instance to log calls to.
position (tuple) – (row, col) position in the figure grid.
Examples
>>> import figrecipe as ps >>> fig, ax = ps.subplots() >>> ax.plot([1, 2, 3], [4, 5, 6], color='red', id='my_line') >>> # The call is recorded automatically
- embed(source, bounds=None, *, ax_key=None, track=True, id=None)[source]
Embed a recipe or diagram as a managed sub-panel that round-trips.
sourcemay be a recipe path, image, FigureRecord, diagram recipe, composed multi-panel recipe, or(source, ax_key).boundsis an axes-fraction[x, y, w, h](defaults to the whole axes). Returns the embedded inset RecordingAxes (or a list for a multi-panel source).
- __dir__()[source]
Return list of attributes for tab completion.
Exposes all matplotlib plotting and decoration methods alongside figrecipe’s custom methods and properties.
- _create_recording_wrapper(method_name, method)[source]
Create a wrapper function that records the call.
- _create_legend_wrapper()[source]
Build the legend() wrapper that handles SCITEX styling + figrecipe loc extensions + recording. Implementation lives in _legend_wrapper.py so this file stays focused.
- set_caption(caption)[source]
Set panel caption metadata (not rendered, stored in recipe).
- Return type:
- set_stats(stats)[source]
Set panel-level statistics metadata (not rendered, stored in recipe).
- Return type:
- _record_seaborn_call(func_name, args, kwargs, data_arrays, call_id=None)[source]
Record a seaborn plotting call.
- Return type:
- property figure
- property xaxis
- property yaxis