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) – Flask server port (default: 5050).

  • host (str, optional) – Host to bind Flask 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)[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)

Returns:

Path to the saved cropped image.

Return type:

Path

figrecipe.info(path)[source]

Get information about a recipe without reproducing.

Return type:

Dict[str, Any]

figrecipe.validate(path, mse_threshold=100.0)

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

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) 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']
figrecipe.get_graph_preset(name)

Get a preset by name.

Parameters:

name (str) – Preset name. Built-in presets: ‘default’, ‘minimal’, ‘citation’, ‘dependency’, ‘social’, ‘biological’, ‘knowledge’.

Returns:

Preset configuration dictionary.

Return type:

dict

Raises:

ValueError – If preset name is not found.

figrecipe.list_graph_presets()

List all available presets with descriptions.

Returns:

Dictionary mapping preset names to brief descriptions.

Return type:

dict

figrecipe.register_graph_preset(name, config, override=False)

Register a custom graph preset.

Parameters:
  • name (str) – Name for the new preset.

  • config (dict) – Preset configuration. Keys should match graph() parameters.

  • override (bool) – If True, allow overriding existing presets.

Raises:

ValueError – If preset already exists and override is False.

Return type:

None

Examples

>>> from figrecipe._graph_presets import register_preset
>>> register_preset('my_style', {
...     'layout': 'circular',
...     'node_color': '#e74c3c',
...     'node_size': 'degree',
...     'labels': True,
... })
class figrecipe.Diagram(type='workflow', title='', column='single')[source]

Bases: object

Paper-optimized diagram with semantic specification.

This class provides the main interface for creating diagrams that compile to Mermaid or Graphviz with paper-appropriate layout constraints.

Examples

>>> # From YAML spec
>>> d = Diagram.from_yaml("workflow.diagram.yaml")
>>> d.to_mermaid("workflow.mmd")
>>> # From existing Mermaid (parse and enhance)
>>> d = Diagram.from_mermaid("existing.mmd", diagram_type="workflow")
>>> d.spec.paper.column = "double"
>>> d.to_mermaid("enhanced.mmd")
>>> # Programmatic creation
>>> d = Diagram(type="pipeline")
>>> d.add_node("input", "Raw Data")
>>> d.add_node("process", "Transform", emphasis="primary")
>>> d.add_node("output", "Results")
>>> d.add_edge("input", "process")
>>> d.add_edge("process", "output")
>>> print(d.to_mermaid())
__init__(type='workflow', title='', column='single')[source]

Initialize a new diagram.

Parameters:
  • type (str) – Diagram type: workflow, decision, pipeline, hierarchy.

  • title (str) – Diagram title.

  • column (str) – Paper column: single or double.

_parse_mermaid(content)[source]

Parse Mermaid content to extract structure.

add_edge(source, target, label=None, style='solid')[source]

Add an edge between nodes.

add_node(id, label, shape='box', emphasis='normal')[source]

Add a node to the diagram.

emphasize(*node_ids)[source]

Mark nodes as emphasized (primary styling).

classmethod from_dict(data)[source]

Create diagram from dictionary specification.

Parameters:

data (dict) – Dictionary with diagram specification.

Returns:

Created diagram.

Return type:

Diagram

classmethod from_mermaid(path, diagram_type='workflow')[source]

Parse existing Mermaid file and create enhanced Diagram.

This allows upgrading existing Mermaid files with FigRecipe paper constraints while preserving the original structure.

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

  • diagram_type (str) – Inferred diagram type.

Returns:

Parsed diagram (can be enhanced and re-exported).

Return type:

Diagram

classmethod from_yaml(path)[source]

Load diagram from YAML specification file.

Parameters:

path (str or Path) – Path to YAML file.

Returns:

Loaded diagram.

Return type:

Diagram

render(path, format='png', backend='auto', scale=2.0)[source]

Render diagram to image file (PNG, SVG, PDF).

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

  • format (str) – Output format: png, svg, pdf.

  • backend (str) – Rendering backend: ‘mermaid-cli’, ‘graphviz’, ‘mermaid.ink’, ‘auto’.

  • scale (float) – Scale factor for output (default: 2.0 for high-res).

Returns:

Path to rendered file.

Return type:

Path

Raises:

RuntimeError – If no rendering backend is available.

set_group(group_name, node_ids)[source]

Define a group of nodes (rendered as subgraph).

split(max_nodes=12, strategy='by_groups', keep_hubs=True)[source]

Split diagram into multiple figures if too large.

Parameters:
  • max_nodes (int) – Maximum nodes per figure before splitting.

  • strategy (str) – Split strategy: “by_groups” or “by_articulation”.

  • keep_hubs (bool) – Show hub nodes as ghosts in both parts.

Returns:

List of split diagrams (or single diagram if no split needed).

Return type:

List[Diagram]

Examples

>>> d = Diagram.from_yaml("large_workflow.yaml")
>>> parts = d.split(max_nodes=8)
>>> for i, part in enumerate(parts):
...     part.to_mermaid(f"workflow_part_{i+1}.mmd")
to_graphviz(path=None)[source]

Compile to Graphviz DOT format.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

Graphviz DOT source code.

Return type:

str

to_mermaid(path=None)[source]

Compile to Mermaid format.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

Mermaid source code.

Return type:

str

to_yaml(path=None)[source]

Export specification as YAML.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

YAML specification.

Return type:

str

class figrecipe.Schematic(title=None, width_mm=170.0, height_mm=120.0)[source]

Bases: object

Builder for rich schematic diagrams.

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

Determine best anchor points automatically.

Return type:

Tuple[str, str]

_get_anchor(pos, anchor)[source]

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

Return type:

Tuple[float, float]

_render_arrow(ax, arrow)[source]

Render an arrow.

Return type:

None

_render_box(ax, bid, box)[source]

Render a rich text box.

Return type:

None

_render_container(ax, cid, container)[source]

Render a container box.

Return type:

None

add_arrow(source, target, source_anchor='auto', target_anchor='auto', label=None, style='solid', color=None, curve=0.0, linewidth_mm=0.5, label_offset_mm=None)[source]

Add an arrow connecting two boxes.

Return type:

Schematic

add_box(id, title, subtitle=None, content=None, emphasis='normal', shape='rounded', position_mm=None, size_mm=None, fill_color=None, border_color=None, title_color=None, padding_mm=5.0, margin_mm=0.0)[source]

Add a rich text box.

Return type:

Schematic

add_container(id, title=None, children=None, emphasis='muted', position_mm=None, size_mm=None, fill_color=None, border_color=None)[source]

Add a container that groups other boxes.

Return type:

Schematic

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 _schematic_layout for details.

Return type:

Schematic

classmethod from_dict(data)[source]

Create Schematic from dictionary (recipe reproduction).

Return type:

Schematic

render(ax=None)[source]

Render the schematic.

Return type:

Tuple[Figure, Axes]

render_to_file(path, dpi=200)[source]

Render and save. On validation failure, saves as *_FAILED.png.

Return type:

Path

to_dict()[source]

Convert schematic 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._get_sns()

Get or create the seaborn recorder instance.

Return type:

SeabornRecorder

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)

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

Returns:

Path to the saved cropped image.

Return type:

Path

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 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=False, **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.

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, SchematicMixin

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) – Flask server port (default: 5050).

  • host (str, optional) – Host to bind Flask 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(type='workflow', title='', column='single')[source]

Paper-optimized diagram with semantic specification.

This class provides the main interface for creating diagrams that compile to Mermaid or Graphviz with paper-appropriate layout constraints.

Examples

>>> # From YAML spec
>>> d = Diagram.from_yaml("workflow.diagram.yaml")
>>> d.to_mermaid("workflow.mmd")
>>> # From existing Mermaid (parse and enhance)
>>> d = Diagram.from_mermaid("existing.mmd", diagram_type="workflow")
>>> d.spec.paper.column = "double"
>>> d.to_mermaid("enhanced.mmd")
>>> # Programmatic creation
>>> d = Diagram(type="pipeline")
>>> d.add_node("input", "Raw Data")
>>> d.add_node("process", "Transform", emphasis="primary")
>>> d.add_node("output", "Results")
>>> d.add_edge("input", "process")
>>> d.add_edge("process", "output")
>>> print(d.to_mermaid())
__init__(type='workflow', title='', column='single')[source]

Initialize a new diagram.

Parameters:
  • type (str) – Diagram type: workflow, decision, pipeline, hierarchy.

  • title (str) – Diagram title.

  • column (str) – Paper column: single or double.

classmethod from_yaml(path)[source]

Load diagram from YAML specification file.

Parameters:

path (str or Path) – Path to YAML file.

Returns:

Loaded diagram.

Return type:

Diagram

classmethod from_dict(data)[source]

Create diagram from dictionary specification.

Parameters:

data (dict) – Dictionary with diagram specification.

Returns:

Created diagram.

Return type:

Diagram

classmethod from_mermaid(path, diagram_type='workflow')[source]

Parse existing Mermaid file and create enhanced Diagram.

This allows upgrading existing Mermaid files with FigRecipe paper constraints while preserving the original structure.

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

  • diagram_type (str) – Inferred diagram type.

Returns:

Parsed diagram (can be enhanced and re-exported).

Return type:

Diagram

_parse_mermaid(content)[source]

Parse Mermaid content to extract structure.

add_node(id, label, shape='box', emphasis='normal')[source]

Add a node to the diagram.

add_edge(source, target, label=None, style='solid')[source]

Add an edge between nodes.

set_group(group_name, node_ids)[source]

Define a group of nodes (rendered as subgraph).

emphasize(*node_ids)[source]

Mark nodes as emphasized (primary styling).

to_mermaid(path=None)[source]

Compile to Mermaid format.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

Mermaid source code.

Return type:

str

to_graphviz(path=None)[source]

Compile to Graphviz DOT format.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

Graphviz DOT source code.

Return type:

str

render(path, format='png', backend='auto', scale=2.0)[source]

Render diagram to image file (PNG, SVG, PDF).

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

  • format (str) – Output format: png, svg, pdf.

  • backend (str) – Rendering backend: ‘mermaid-cli’, ‘graphviz’, ‘mermaid.ink’, ‘auto’.

  • scale (float) – Scale factor for output (default: 2.0 for high-res).

Returns:

Path to rendered file.

Return type:

Path

Raises:

RuntimeError – If no rendering backend is available.

to_yaml(path=None)[source]

Export specification as YAML.

Parameters:

path (str or Path, optional) – If provided, write to file.

Returns:

YAML specification.

Return type:

str

split(max_nodes=12, strategy='by_groups', keep_hubs=True)[source]

Split diagram into multiple figures if too large.

Parameters:
  • max_nodes (int) – Maximum nodes per figure before splitting.

  • strategy (str) – Split strategy: “by_groups” or “by_articulation”.

  • keep_hubs (bool) – Show hub nodes as ghosts in both parts.

Returns:

List of split diagrams (or single diagram if no split needed).

Return type:

List[Diagram]

Examples

>>> d = Diagram.from_yaml("large_workflow.yaml")
>>> parts = d.split(max_nodes=8)
>>> for i, part in enumerate(parts):
...     part.to_mermaid(f"workflow_part_{i+1}.mmd")