FigRecipe API Reference

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()
  • fr.utils: Unit conversions, font checks, low-level recipe access

  • fr.styles: Axis helpers, spine management, plot styling functions

  • fr.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[int, ...], dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]]]

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', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=True)[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’.

  • 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.

Returns:

If save_recipe=True: (image_path, yaml_path, ValidationResult or None) If save_recipe=False: (image_path, None, None)

Return type:

tuple

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:

Tuple[Figure, Union[Axes, List[Axes]]]

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:

Tuple[Figure, Union[Axes, List[Axes]]]

Returns:

  • fig (matplotlib.figure.Figure) – Reproduced figure.

  • axes (Axes or list of Axes) – Reproduced axes.

figrecipe.compose(sources, layout=None, canvas_size_mm=None, gap_mm=5.0, dpi=300, panel_labels=False, label_style='uppercase', **kwargs)[source]

Compose a new figure from multiple sources (recipes or raw images).

Supports two modes automatically detected from sources format:

  1. Grid-based: sources={(row, col): path} Uses layout=(nrows, ncols) for subplot grid.

  2. Mm-based: sources={path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} Uses canvas_size_mm for precise positioning.

Parameters:
  • sources (dict) – Either: - Grid-based: {(row, col): source_path} mapping positions to sources - Mm-based: {source_path: {“xy_mm”: (x, y), “size_mm”: (w, h)}}

  • layout (tuple, optional) – (nrows, ncols) for grid-based composition. Auto-detected if not provided.

  • canvas_size_mm (tuple, optional) – (width_mm, height_mm) for mm-based composition. Required for mm-based mode.

  • gap_mm (float) – Gap between panels in mm (for auto-layout modes like ‘horizontal’).

  • 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’.

  • **kwargs – Additional arguments passed to figure creation.

Return type:

Tuple[RecordingFigure, Union[RecordingAxes, ndarray[tuple[int, ...], dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]], 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",
...     }
... )

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)},
...     }
... )
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:

None

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:

None

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:

None

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:

dict

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.info(path)[source]

Get information about a recipe without reproducing.

Return type:

Dict[str, Any]

figrecipe.validate(path, mse_threshold=100.0)[source]

Validate that a saved recipe can reproduce its original figure.

Parameters:
  • path (str or Path) – Path to .yaml recipe file.

  • mse_threshold (float) – Maximum acceptable MSE for validation to pass (default: 100).

Returns:

Detailed comparison results.

Return type:

ValidationResult

figrecipe.extract_data(path)[source]

Extract data arrays from a saved recipe.

Returns:

Nested dictionary: {call_id: {‘x’: array, ‘y’: array, …}}

Return type:

dict

class figrecipe.Figz(path)[source]

Bases: object

Multi-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)
__init__(path)[source]
add_panel(label, pltz_source, position=None, size=None)[source]

Add a .plt.zip panel to this figure.

Parameters:
  • label (str) – Panel label (e.g., “A”, “B”).

  • pltz_source (bytes, str, or Path) – Panel bytes or path to a .plt.zip file.

  • 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:

None

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:

None

classmethod create(path, name, size_mm=None)[source]

Create a new empty .fig.zip bundle.

Parameters:
  • path (str or Path) – Output path (should end in .fig.zip).

  • name (str) – Figure name / ID.

  • size_mm (dict, optional) – Canvas size e.g. {“width_mm”: 170, “height_mm”: 120}.

Returns:

Loaded Figz instance.

Return type:

Figz

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).

Parameters:

label (str) – Panel label.

Returns:

Loaded Pltz instance for the panel.

Return type:

Pltz

get_panel_data(panel_id)[source]

Get panel’s CSV data as DataFrame.

Parameters:

panel_id (str) – Panel label.

Return type:

DataFrame or None

get_panel_pltz(panel_id)[source]

Get panel as raw bytes.

Parameters:

panel_id (str) – Panel label.

Returns:

Raw .plt.zip bytes, or None if panel not found.

Return type:

bytes or None

list_panel_ids()[source]

List panel labels in order.

Returns:

Panel labels.

Return type:

list of str

remove_panel(label)[source]

Remove a panel (rebuilds ZIP).

Parameters:

label (str) – Panel label to remove.

Return type:

None

render_preview()[source]

Return preview of first panel as PNG bytes.

Return type:

bytes or None

save()[source]

Save spec/style changes back to bundle.

Return type:

None

class figrecipe.Pltz(path)[source]

Bases: object

Single-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

__init__(path)[source]
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:

Pltz

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:
  • png_bytes (bytes) – PNG image data.

  • path (str or Path) – Output path for the .plt.zip file.

  • plot_type (str, optional) – Plot type label stored in spec.json (default: “image”).

  • spec (dict, optional) – Additional spec entries (default: {}).

  • style (dict, optional) – Style entries (default: {}).

Returns:

Loaded Pltz instance wrapping the saved bundle.

Return type:

Pltz

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

reproduce()[source]

Reproduce figure from bundle.

Returns:

(fig, axes) reproduced from bundle.

Return type:

tuple

save()[source]

Save spec/style changes back to bundle in-place.

Updates spec.json and style.json inside the ZIP without re-rendering the figure.

Return type:

None

update_preview()[source]

Re-render and update preview PNG in bundle.

Return type:

None

figrecipe.save_bundle(fig, path, dpi=None, image_formats=None, save_hitmap=True, 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

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 hitmap for GUI editing (default: True).

  • verbose (bool) – Whether to print status (default: True).

Returns:

Path to saved ZIP bundle.

Return type:

Path

figrecipe.load_bundle(path)[source]

Load bundle components from ZIP file.

Parameters:

path (str or Path) – Path to bundle ZIP file.

Returns:

(spec, style, data) where data is DataFrame or None.

Return type:

tuple

figrecipe.reproduce_bundle(path, apply_style=True)[source]

Reproduce figure from bundle.

Parameters:
  • path (str or Path) – Path to bundle (ZIP file or directory).

  • apply_style (bool) – Whether to apply saved style (default: True).

Returns:

(fig, axes) reproduced from bundle.

Return type:

tuple

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.

Returns:

Names of available presets.

Return type:

list of str

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: object

Builder for rich box-and-arrow diagrams with mm-based coordinates.

__init__(title=None, width_mm=170.0, height_mm=120.0, padding_mm=10.0, gap_mm=None)[source]
_auto_anchor(src, tgt)[source]

Determine best anchor points automatically.

Return type:

Tuple[str, str]

_auto_box_height(box)[source]

Compute box height from content when height_mm is not specified.

Return type:

float

_finalize_canvas_size()[source]

Compute canvas height from element positions when height_mm=None.

Return type:

None

_get_anchor(pos, anchor)[source]

Get absolute position of an anchor point on the visual box edge.

Return type:

Tuple[float, float]

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:

Diagram

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:

Diagram

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:

Diagram

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:

Diagram

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:

Diagram

classmethod from_dict(data)[source]

Create Diagram from dictionary (recipe reproduction).

Return type:

Diagram

render(ax=None, auto_fix=False, auto_curve=True)[source]

Render. auto_fix=True resolves violations; auto_curve=False skips R7.

Return type:

Tuple[Figure, Axes]

render_to_file(path, dpi=200, save_recipe=True, save_hitmap=True, save_debug=True, watermark=False)

Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.

Return type:

Path

save(path, dpi=200, save_recipe=True, save_hitmap=True, save_debug=True, watermark=False)[source]

Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.

Return type:

Path

to_dict()[source]

Convert diagram to dictionary for serialization.

Return type:

Dict[str, Any]

validate_containers()[source]

Check every container fully encloses its declared children.

Return type:

None

validate_no_overlap()[source]

Check that no two boxes overlap each other.

Return type:

None

figrecipe.signature(image_path=None, recipe_path=None)[source]

Compute verification signature for a saved figure.

Parameters:
  • image_path (str or Path, optional) – Path to the saved image file.

  • recipe_path (str or Path, optional) – Path to the saved recipe YAML file.

Returns:

Signature with keys: image_hash, recipe_hash, image_path, recipe_path.

Return type:

dict

figrecipe.caption_with_signature(caption, image_path=None, recipe_path=None, style='short')[source]

Append verification signature to a figure caption.

Parameters:
  • caption (str) – Original caption text.

  • image_path (str or Path, optional) – Path to the saved image.

  • recipe_path (str or Path, optional) – Path to the saved recipe YAML.

  • style (str) – ‘short’ (default): hash only. ‘full’: includes “Generated by figrecipe” prefix.

Returns:

Caption with appended signature.

Return type:

str

figrecipe._Graphviz

alias of Graphviz

figrecipe._Mermaid

alias of Mermaid

figrecipe._get_version(distribution_name)

Get the version string for the named package.

Parameters:

distribution_name – The name of the distribution package to query.

Returns:

The version string for the package as defined in the package’s “Version” metadata key.

figrecipe._rebrand_text(text)

Apply branding to a text string (e.g., docstring).

Parameters:

text (str or None) – Text to rebrand.

Returns:

Rebranded text, or None if input was None.

Return type:

str or None

Examples

>>> os.environ["FIGRECIPE_BRAND"] = "mypackage"
>>> os.environ["FIGRECIPE_ALIAS"] = "mp"
>>> rebrand_text("import figrecipe as fr")
'import mypackage as mp'

Core Functions

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[int, ...], dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]]]

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', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=True)[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’.

  • 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.

Returns:

If save_recipe=True: (image_path, yaml_path, ValidationResult or None) If save_recipe=False: (image_path, None, None)

Return type:

tuple

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:

Tuple[Figure, Union[Axes, List[Axes]]]

Returns:

  • fig (matplotlib.figure.Figure) – Reproduced figure.

  • axes (Axes or list of Axes) – Reproduced axes.

figrecipe.compose(sources, layout=None, canvas_size_mm=None, gap_mm=5.0, dpi=300, panel_labels=False, label_style='uppercase', **kwargs)[source]

Compose a new figure from multiple sources (recipes or raw images).

Supports two modes automatically detected from sources format:

  1. Grid-based: sources={(row, col): path} Uses layout=(nrows, ncols) for subplot grid.

  2. Mm-based: sources={path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} Uses canvas_size_mm for precise positioning.

Parameters:
  • sources (dict) – Either: - Grid-based: {(row, col): source_path} mapping positions to sources - Mm-based: {source_path: {“xy_mm”: (x, y), “size_mm”: (w, h)}}

  • layout (tuple, optional) – (nrows, ncols) for grid-based composition. Auto-detected if not provided.

  • canvas_size_mm (tuple, optional) – (width_mm, height_mm) for mm-based composition. Required for mm-based mode.

  • gap_mm (float) – Gap between panels in mm (for auto-layout modes like ‘horizontal’).

  • 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’.

  • **kwargs – Additional arguments passed to figure creation.

Return type:

Tuple[RecordingFigure, Union[RecordingAxes, ndarray[tuple[int, ...], dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]], 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",
...     }
... )

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)},
...     }
... )
figrecipe.validate(path, mse_threshold=100.0)[source]

Validate that a saved recipe can reproduce its original figure.

Parameters:
  • path (str or Path) – Path to .yaml recipe file.

  • mse_threshold (float) – Maximum acceptable MSE for validation to pass (default: 100).

Returns:

Detailed comparison results.

Return type:

ValidationResult

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.info(path)[source]

Get information about a recipe without reproducing.

Return type:

Dict[str, Any]

figrecipe.extract_data(path)[source]

Extract data arrays from a saved recipe.

Returns:

Nested dictionary: {call_id: {‘x’: array, ‘y’: array, …}}

Return type:

dict

Recording Classes

These classes are available via from figrecipe import utils or from figrecipe._wrappers import RecordingFigure, RecordingAxes.

class figrecipe._wrappers.RecordingFigure(fig, recorder, axes)[source]

Bases: object

Wrapper around matplotlib Figure that manages recording.

Parameters:

Examples

>>> import figrecipe as ps
>>> fig, ax = ps.subplots()
>>> ax.plot([1, 2, 3], [4, 5, 6])
>>> ps.save(fig, "my_figure.yaml")
__init__(fig, recorder, axes)[source]
property fig: Figure

Get the underlying matplotlib figure.

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_style_fontsize(key, default)[source]

Get fontsize from loaded style.

Return type:

float

_get_theme_text_color(default='black')[source]

Get text color from loaded style’s theme settings.

Return type:

str

suptitle(t, **kwargs)[source]

Set super title for the figure and record it.

Parameters:
  • t (str) – The super title text.

  • **kwargs – Additional arguments passed to matplotlib’s suptitle().

Returns:

The matplotlib Text object.

Return type:

Text

supxlabel(t, **kwargs)[source]

Set super x-label for the figure and record it.

Parameters:
  • t (str) – The super x-label text.

  • **kwargs – Additional arguments passed to matplotlib’s supxlabel().

Returns:

The matplotlib Text object.

Return type:

Text

supylabel(t, **kwargs)[source]

Set super y-label for the figure and record it.

Parameters:
  • t (str) – The super y-label text.

  • **kwargs – Additional arguments passed to matplotlib’s supylabel().

Returns:

The matplotlib Text object.

Return type:

Text

colorbar(mappable, ax=None, **kwargs)[source]

Add a colorbar and record it for reproduction.

Return type:

Any

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:

RecordingFigure

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:

RecordingFigure

Examples

>>> fig, ax = fr.subplots()
>>> fig.set_caption("Figure 1. Temperature dependence of reaction rates.")
property title_metadata: str | None

Get the figure title metadata.

property caption: str | None

Get the figure caption metadata.

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:

RecordingFigure

property stats: Dict[str, Any] | None

Get the figure-level statistics metadata.

generate_caption(style='publication', template=None)[source]

Generate caption from stored stats. Styles: publication, brief, detailed.

Return type:

str

__getattr__(name)[source]

Delegate attribute access to underlying figure.

Return type:

Any

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=True, **kwargs)[source]

Save figure — equivalent to fr.save(). Same DPI, crop, recipe.

Returns (image_path, yaml_path, result). **kwargs passed to matplotlib savefig for file-like objects.

set_supxyt(xlabel=None, ylabel=None, title=None, **kwargs)[source]

Set supxlabel, supylabel, and suptitle in one call.

Parameters:
  • xlabel (str, optional)

  • ylabel (str, optional)

  • title (str, optional)

  • **kwargs (dict) – Passed to the underlying methods.

Return type:

RecordingFigure

Examples

>>> fig.set_supxyt('Time (s)', 'Amplitude', 'All Channels')
set_supxytc(xlabel=None, ylabel=None, title=None, caption=None, **kwargs)[source]

Set supxlabel, supylabel, suptitle, and caption in one call.

Parameters:
  • xlabel (str, optional)

  • ylabel (str, optional)

  • title (str, optional)

  • caption (str, optional) – Figure caption metadata (stored in recipe, not rendered).

  • **kwargs (dict) – Passed to the underlying methods.

Return type:

RecordingFigure

Examples

>>> fig.set_supxytc('Time', 'Voltage', 'Neural Data',
...                 'Figure 1. Overview of neural recordings.')
save_recipe(path, include_data=True, data_format='csv', csv_format='separate')[source]

Save the recording recipe to YAML.

Parameters:
  • path (str or Path) – Output path for the recipe file.

  • include_data (bool) – If True, save array data alongside recipe.

  • data_format (str) – Format for data files: ‘csv’ (default), ‘npz’, or ‘inline’.

  • csv_format (str) – CSV structure: ‘separate’ (default) or ‘single’ (scitex-compatible).

Return type:

Path

class figrecipe._wrappers.RecordingAxes(ax, recorder, position=(0, 0))[source]

Bases: RecordingAxesMethods, AxesStyleMixin, SciTexMixin, DiagramMixin

Wrapper 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
__init__(ax, recorder, position=(0, 0))[source]
property ax: Axes

Get the underlying matplotlib axes.

property position: Tuple[int, int]

Get axes position in grid.

__getattr__(name)[source]

Intercept attribute access to wrap methods.

Return type:

Any

__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_bar_wrapper()[source]

Create wrapper for bar() with SCITEX error bar styling.

_create_boxplot_wrapper()[source]

Create wrapper for boxplot() with patch_artist=True default.

_create_stem_wrapper()[source]

Create wrapper for stem() that accepts color kwarg.

_create_legend_wrapper()[source]

Create wrapper for legend() that applies frame styling and records the call.

set_caption(caption)[source]

Set panel caption metadata (not rendered, stored in recipe).

Return type:

RecordingAxes

property panel_caption: str | None

Get the panel caption metadata.

set_stats(stats)[source]

Set panel-level statistics metadata (not rendered, stored in recipe).

Return type:

RecordingAxes

property stats: Dict[str, Any] | None

Get the panel-level statistics metadata.

_no_record()[source]

Context manager to temporarily disable recording (internal).

_record_seaborn_call(func_name, args, kwargs, data_arrays, call_id=None)[source]

Record a seaborn plotting call.

Return type:

None

property figure
property xaxis
property yaxis
get_xlim()[source]
get_ylim()[source]
get_xlabel()[source]
get_ylabel()[source]
get_title()[source]
property caption: str | None

Get the panel caption metadata.

generate_panel_caption(label=None, style='publication')[source]

Generate a caption for this panel from stats metadata.

Return type:

str

Style Management

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.

Returns:

Names of available presets.

Return type:

list of str

Examples

>>> import figrecipe as ps
>>> ps.list_presets()
['MINIMAL', 'PRESENTATION', 'SCIENTIFIC']

Alignment Functions

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:

None

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.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:

None

Examples

>>> import figrecipe as fr
>>> fig, axes = fr.subplots(2, 2)
>>> # ... add plots ...
>>> fr.align_smart(fig)  # Align all panels using theme settings
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:

None

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)

GUI Editor

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:

dict

Diagram Class

class figrecipe.Diagram(title=None, width_mm=170.0, height_mm=120.0, padding_mm=10.0, gap_mm=None)[source]

Builder for rich box-and-arrow diagrams with mm-based coordinates.

__init__(title=None, width_mm=170.0, height_mm=120.0, padding_mm=10.0, gap_mm=None)[source]
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:

Diagram

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:

Diagram

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:

Diagram

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:

Diagram

validate_containers()[source]

Check every container fully encloses its declared children.

Return type:

None

validate_no_overlap()[source]

Check that no two boxes overlap each other.

Return type:

None

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:

Diagram

_auto_box_height(box)[source]

Compute box height from content when height_mm is not specified.

Return type:

float

_finalize_canvas_size()[source]

Compute canvas height from element positions when height_mm=None.

Return type:

None

_get_anchor(pos, anchor)[source]

Get absolute position of an anchor point on the visual box edge.

Return type:

Tuple[float, float]

_auto_anchor(src, tgt)[source]

Determine best anchor points automatically.

Return type:

Tuple[str, str]

render(ax=None, auto_fix=False, auto_curve=True)[source]

Render. auto_fix=True resolves violations; auto_curve=False skips R7.

Return type:

Tuple[Figure, Axes]

save(path, dpi=200, save_recipe=True, save_hitmap=True, save_debug=True, watermark=False)[source]

Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.

Return type:

Path

render_to_file(path, dpi=200, save_recipe=True, save_hitmap=True, save_debug=True, watermark=False)

Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.

Return type:

Path

to_dict()[source]

Convert diagram to dictionary for serialization.

Return type:

Dict[str, Any]

classmethod from_dict(data)[source]

Create Diagram from dictionary (recipe reproduction).

Return type:

Diagram