FigRecipe API Reference
The full public surface of figrecipe is documented inline below
via automodule. The __all__ declaration in
figrecipe/__init__.py is the single source of truth for what
appears here; do NOT add explicit autofunction / autoclass
directives below — Sphinx already discovers them through
automodule :members: and a second declaration triggers
duplicate object description warnings (treated as errors on PR
builds).
figrecipe - Record and reproduce matplotlib figures.
A lightweight library for capturing matplotlib plotting calls and reproducing figures from saved recipes.
Usage
>>> import figrecipe as fr
>>> fig, ax = fr.subplots()
>>> ax.plot(x, y, id='my_data')
>>> fr.save(fig, 'recipe.yaml')
Examples
Recording a figure:
>>> import figrecipe as fr
>>> import numpy as np
>>>
>>> x = np.linspace(0, 10, 100)
>>> y = np.sin(x)
>>>
>>> fig, ax = fr.subplots()
>>> ax.plot(x, y, color='red', linewidth=2, id='sine_wave')
>>> ax.set_xlabel('Time')
>>> ax.set_ylabel('Amplitude')
>>> fr.save(fig, 'my_figure.yaml')
Reproducing a figure:
>>> fig, ax = fr.reproduce('my_figure.yaml')
>>> plt.show()
Notes
Submodules:
fr.utils: Unit conversions, font checks, low-level recipe accessfr.styles: Axis helpers, spine management, plot styling functionsfr.viz: Diagram and graph visualization utilities
>>> from figrecipe import utils
>>> utils.mm_to_inch(25.4) # Unit conversions
>>> from figrecipe import styles
>>> styles.hide_spines(ax) # Spine management
- figrecipe.subplots(nrows=1, ncols=1, axes_width_mm=None, axes_height_mm=None, margin_left_mm=None, margin_right_mm=None, margin_bottom_mm=None, margin_top_mm=None, space_w_mm=None, space_h_mm=None, style=None, apply_style_mm=True, panel_labels=None, **kwargs)[source]
Create a figure with recording-enabled axes.
This is a drop-in replacement for plt.subplots() that wraps the returned figure and axes with recording capabilities.
Supports mm-based layout control for publication-quality figures.
- Parameters:
nrows (
int) – Number of rows and columns of subplots.ncols (
int) – Number of rows and columns of subplots.margin_left_mm (
Optional[float]) – Left/right margins in mm.margin_right_mm (
Optional[float]) – Left/right margins in mm.margin_bottom_mm (
Optional[float]) – Bottom/top margins in mm.space_w_mm (
Optional[float]) – Horizontal/vertical spacing between axes in mm.space_h_mm (
Optional[float]) – Horizontal/vertical spacing between axes in mm.style (
Optional[Dict[str,Any]]) – Style configuration dictionary.apply_style_mm (
bool) – If True (default), apply loaded style to axes.panel_labels (
Optional[bool]) – If True, add panel labels (A, B, C, …).**kwargs – Additional arguments passed to plt.subplots().
- Return type:
Tuple[RecordingFigure,Union[RecordingAxes,NDArray]]- Returns:
fig (RecordingFigure) – Wrapped figure object.
axes (RecordingAxes or ndarray) – Wrapped axes.
- figrecipe.save(fig, path, save_recipe=True, include_data=True, data_format='csv', csv_format='separate', validate=True, validate_mse_threshold=100.0, validate_error_level='error', validate_axis_range_alignment=True, validate_axis_range_alignment_error_level='warning', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=False, save_editable=False)[source]
Save a figure as image and recipe. Unified API with fig.savefig().
- Parameters:
fig (
Union[RecordingFigure,Figure]) – The figure to save.path (
Union[str,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 (
Literal['csv','npz','inline']) – Format for data files: ‘csv’, ‘npz’, or ‘inline’.csv_format (
Literal['single','separate']) – CSV structure: ‘separate’ (default) or ‘single’ (scitex-compatible).validate (
bool) – If True (default), validate reproducibility after saving.validate_mse_threshold (
float) – Maximum acceptable MSE for validation (default: 100).validate_error_level (
str) – How to handle failures: ‘error’, ‘warning’, or ‘debug’.validate_axis_range_alignment (
bool) – If True (default), run the runtimeaxis_range_alignmentcheck on the rendered figure. Catches the autoscale-with- different-data case that the static STX-FIG001 lint misses.validate_axis_range_alignment_error_level (
str) – Dispatch level for the axis-range-alignment check: ‘warning’ (default), ‘error’, or ‘debug’ (silent).verbose (
bool) – If True (default), print save status.image_format (
Optional[str]) – Image format when path is YAML.facecolor (
Optional[str]) – Background color. When opaque, patches are made visible.save_hitmap (
bool) – If True (default), save hitmap image for GUI editor element selection.save_editable (
bool) – If True, write the editable-figure JSON (schemascitex.plt.figure.editable) to<stem>.jsonnext to the image. Default False — opt in for the GUI / web editor.
- Returns:
If save_recipe=True: (image_path, yaml_path, ValidationResult or None) If save_recipe=False: (image_path, None, None)
- Return type:
- figrecipe.reproduce(path, calls=None, skip_decorations=False, apply_style=True)[source]
Reproduce a figure from a recipe file or bundle.
- Parameters:
path (
Union[str,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 (
Optional[List[str]]) – If provided, only reproduce these specific call IDs.skip_decorations (
bool) – If True, skip decoration calls.apply_style (
bool) – If True (default), apply saved style.
- Return type:
- Returns:
fig (matplotlib.figure.Figure) – Reproduced figure.
axes (Axes or list of Axes) – Reproduced axes.
- figrecipe.load(path, calls=None, skip_decorations=False, apply_style=True)
Reproduce a figure from a recipe file or bundle.
- Parameters:
path (
Union[str,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 (
Optional[List[str]]) – If provided, only reproduce these specific call IDs.skip_decorations (
bool) – If True, skip decoration calls.apply_style (
bool) – If True (default), apply saved style.
- Return type:
- Returns:
fig (matplotlib.figure.Figure) – Reproduced figure.
axes (Axes or list of Axes) – Reproduced axes.
- figrecipe.compose(sources, layout=None, canvas_size_mm=None, width_mm=None, gap_mm=2.0, dpi=300, panel_labels=False, label_style='uppercase', caption=None, panel_captions=None, max_whitespace_frac=None, **kwargs)[source]
Compose a new figure from multiple sources (recipes or raw images).
Supports three modes automatically detected from sources/layout format:
Grid-based: sources={(row, col): path} Uses layout=(nrows, ncols) for subplot grid.
Mm-based: sources={path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} Uses canvas_size_mm for precise positioning.
Tiled (row-justified, whitespace-free): layout=[[“A”,”B”,”C”],[“D”]] (or the multiline string “A B CnD”) with sources={“A”: path, …}. Each panel keeps its true aspect ratio; within a row all panels share one common height and sit edge-to-edge (only
gap_mmbetween) so there is no whitespace, and every row spans the same width so the right edge is never ragged. The first layout row is rendered on top.
- Parameters:
sources (
Dict[Any,Any]) – One of: - Grid-based: {(row, col): source_path} mapping positions to sources - Mm-based: {source_path: {“xy_mm”: (x, y), “size_mm”: (w, h)}} - Tiled: {label: source} keyed by the string labels used inlayoutlayout (
Union[Tuple[int,int],str,List[List[str]],None]) –(nrows, ncols) for grid-based composition (auto-detected if omitted).
list of rows of labels (
[["A","B"],["C"]]) or a multiline string ("A B\nC") for tiled composition.
canvas_size_mm (
Optional[Tuple[float,float]]) – (width_mm, height_mm) for mm-based composition. Required for mm-based mode.width_mm (
Optional[float]) – Overall content width (mm) for TILED composition. When omitted the default width is the widest row at its true content size, i.e.max over rows of (sum of true panel widths + (k-1)*gap_mm). Ignored by grid/mm modes.gap_mm (
float) – Gap between panels in mm (gutter; tiled mode uses it as the edge-to-edge spacing, andgap_mm=0makes panels share edges exactly).dpi (
int) – DPI for the output figure.panel_labels (
bool) – If True, add panel labels (A, B, C…) to each panel.label_style (
str) – ‘uppercase’, ‘lowercase’, or ‘numeric’.caption (
Optional[str]) – Figure-level caption text. Rendered on the figure and persisted in the recipe so it survives save→reproduce.panel_captions (
Optional[List[str]]) – Per-panel caption texts. When provided, panel labels (A, B, C…) are placed with the corresponding caption text on each panel.max_whitespace_frac (
Optional[float]) – Refuse the composite when more than this fraction of the canvas is blank — e.g.0.4raises above 40% whitespace, naming the measured figure and the largest empty regions. Omitted (the default) measures without enforcing: a composite over half blank warns, nothing raises. Enforcement is opt-in because a raising default would break every existing sparse composite at once.**kwargs – Additional arguments passed to figure creation.
- Return type:
Tuple[RecordingFigure,Union[RecordingAxes,NDArray,List[RecordingAxes]]]- Returns:
fig (RecordingFigure) – Composed figure (editable, recordable).
axes (RecordingAxes, ndarray, or list) – Axes of the composed figure.
Examples
Grid-based composition:
>>> fig, axes = fr.compose( ... layout=(1, 2), ... sources={ ... (0, 0): "panel_a.yaml", ... (0, 1): "panel_b.yaml", ... } ... )
Composition with figure-level caption:
>>> fig, axes = fr.compose( ... layout=(2, 2), ... sources={ ... (0, 0): "a.yaml", (0, 1): "b.yaml", ... (1, 0): "c.yaml", (1, 1): "d.yaml", ... }, ... caption="Figure 1. Four-condition comparison (n=3).", ... )
Mm-based free-form composition:
>>> fig, axes = fr.compose( ... canvas_size_mm=(180, 120), ... sources={ ... "panel_a.yaml": {"xy_mm": (0, 0), "size_mm": (85, 55)}, ... "panel_b.yaml": {"xy_mm": (90, 0), "size_mm": (85, 55)}, ... "panel_c.yaml": {"xy_mm": (0, 60), "size_mm": (175, 55)}, ... } ... )
Tiled (row-justified, whitespace-free) composition:
>>> fig, axes = fr.compose( ... layout=[["A", "B", "C"], ["D"]], ... sources={"A": "a.yaml", "B": "b.yaml", ... "C": "c.yaml", "D": "d.yaml"}, ... width_mm=180, gap_mm=1.0, ... )
- figrecipe.align_panels(fig, panels, mode, reference=None)[source]
Align multiple panels to a reference panel.
- Parameters:
fig (
RecordingFigure) – The figure containing the panels.panels (
List[Tuple[int,int]]) – List of (row, col) positions to align.mode (
Union[str,AlignmentMode]) – Alignment mode: ‘left’, ‘right’, ‘top’, ‘bottom’, ‘center_h’, ‘center_v’, ‘axis_x’, ‘axis_y’.reference (
Optional[Tuple[int,int]]) – Reference panel position. If None, uses first panel.
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # Align left column panels to left edge >>> fr.align_panels(fig, [(0, 0), (1, 0)], mode="left")
- figrecipe.distribute_panels(fig, panels, direction='horizontal', spacing_mm=None)[source]
Distribute panels evenly with optional fixed spacing.
- Parameters:
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(1, 3) >>> # Distribute evenly >>> fr.distribute_panels(fig, [(0, 0), (0, 1), (0, 2)]) >>> # With fixed 5mm spacing >>> fr.distribute_panels(fig, [(0, 0), (0, 1), (0, 2)], spacing_mm=5)
- figrecipe.align_smart(fig, panels=None)[source]
Automatically align panels in a compact grid layout.
Works like human behavior: 1. Detect grid structure (nrows, ncols) 2. Place panels from top-left to bottom-right 3. Calculate minimum rectangle to cover all content in each row/column 4. Unify row heights and column widths 5. Use space effectively with theme margins and spacing
Uses margin and spacing values from the loaded SCITEX theme: - margins.left_mm, margins.right_mm, margins.top_mm, margins.bottom_mm - spacing.horizontal_mm, spacing.vertical_mm
- Parameters:
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # ... add plots ... >>> fr.align_smart(fig) # Align all panels using theme settings
- figrecipe.empty_cells(layout, sources)[source]
Blank
(row, col)cells of a GRID compose (deterministic fast path).For grid composition (
layout=(nrows, ncols)withsourceskeyed by(row, col)), returns the cells with no source ={all cells} - set(sources keys), sorted row-major. Whenlayoutis omitted it is inferred from the max present (row, col). Returns[]for non-grid (tiled/mm) layouts — those are whitespace-free by construction and have no grid-cell concept.
- figrecipe.layout_report(fig)[source]
Structured, machine-readable layout of a composed figure.
Returns a dict with:
mode(grid/mm/tiled when known),canvas_mm,panels(per-panel*_frac/*_mmbox +aspect),empty_regions(maximal blank rectangles), andcoverage_frac(fraction of the canvas covered by panels). An agent reads this to propose panel target sizes for a tight, no-stretch re-tiling.
- figrecipe.auto_tile_layout(aspects, width_mm, height_mm=None, gap_mm=1.0)[source]
Bin-pack panel aspect ratios into a tight
layoutforbuild_tiled_sources.- Parameters:
aspects (
Dict[str,float]) –{label: w/h}– each panel’s TRUE aspect ratio. Never a size to target; only a ratio the packer must preserve exactly.width_mm (
float) – Overall content widthWof the figure in mm (same role asbuild_tiled_sources’swidth_mm).height_mm (
float) – Target overall canvas height in mm. When given, the packer searches row-counts and picks the one whose resulting total height is closest toheight_mmwithout exceeding it (falling back to the closest overall if every candidate exceeds it). When omitted, the packer instead MINIMISES wasted canvas area (thewidth_mm x total_heightbounding box minus the summed true panel areas) – the canonical packing-efficiency objective.gap_mm (
float) – Gutter between adjacent panels (both within a row and between rows), same convention asbuild_tiled_sources.
- Return type:
Tuple[List[List[str]],Dict[str,Tuple[float,float]],Tuple[float,float]]- Returns:
layout (list of list of str) – Row-list of labels, ready to hand to
build_tiled_sources(orfr.compose) verbatim.sizes_mm (dict) –
{label: (width_mm, height_mm)}– the target size each panel should be RE-AUTHORED/re-plotted at. Every panel’sw/hhere equalsaspects[label]exactly (to floating-point precision): this function only ever proposes geometry, it never stretches or upscales a panel.canvas_size_mm (tuple) –
(width_mm, total_height_mm)of the resulting canvas.
Notes
For each candidate row-count
n_rows(searched over1..len(aspects)) labels are greedily partitioned by_greedy_partition()(largest aspect first, into whichever row has the smallest running aspect-sum – this keeps row heights close to parity). Each row is then sized by the SAME formulabuild_tiled_sourcesuses (seefigrecipe._composition._tile._row_height_mm): row heighth_r = (width_mm - (k-1) * gap_mm) / sum(row aspects), panel widthw_i = aspect_i * h_r. Row order (top-to-bottom) and each row’s internal label order follow assignment order and are never reshuffled afterwards.
- 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) – Django server port (default: 5050).host (
str) – Host to bind server (default: “127.0.0.1”, use “0.0.0.0” for Docker).open_browser (
bool) – Whether to open browser automatically (default: True).hot_reload (
bool) – Enable hot reload (default: False).working_dir (str or Path, optional) – Working directory for file browser (default: directory containing source).
desktop (
bool) – Launch as native desktop window using pywebview (default: False). Requires: pip install figrecipe[desktop]
- Returns:
Final style overrides after editing session.
- Return type:
- figrecipe.crop(input_path, output_path=None, margin_mm=1.0, margin_px=None, overwrite=False, verbose=False, return_offset=False)[source]
Crop a figure image to its content area with a specified margin.
- Parameters:
input_path (str or Path) – Path to the input image.
output_path (str or Path, optional) – Path to save the cropped image.
margin_mm (float, optional) – Margin in millimeters (default: 1.0mm).
margin_px (int, optional) – Margin in pixels (overrides margin_mm if provided).
overwrite (bool, optional) – Whether to overwrite the input file (default: False)
verbose (bool, optional) – Whether to print detailed information (default: False)
return_offset (bool, optional) – If True, also return crop offset info dict (default: False)
- Returns:
Path to the saved cropped image. If return_offset=True, returns (path, offset_dict).
- Return type:
Path or tuple
- figrecipe.validate(path, mse_threshold=100.0)[source]
Validate that a saved recipe can reproduce its original figure.
- figrecipe.add_qr_to_figure(fig, metadata, position='bottom-right', size=0.08)[source]
Add a minimal QR code to a matplotlib figure.
- Parameters:
fig (matplotlib.figure.Figure) – Target figure to overlay onto.
metadata (dict) – Payload to encode. If
"url"is absent,"https://scitex.ai"is added so the QR resolves to something even when consumers don’t provide one.position (str) – One of
"bottom-right","bottom-left","top-right","top-left". Unknown values fall back to"bottom-right".size (float) – Relative size of the QR overlay (fraction of figure width).
- Returns:
The same figure, with a QR overlay axes added. If the optional
qrcode/Pillowdependencies are not installed, the figure is returned unmodified and a warning is logged.- Return type:
- figrecipe.add_figure_caption(fig, caption, *, figure_label=None, style='scientific', position='bottom', width_ratio=0.9, font_size='small', wrap_width=80, align='justify', pad_mm=2.0, save_to_file=False, file_path=None)[source]
Add a figure caption.
The caption text is stripped of Markdown formatting (bold/italic) so it renders cleanly in matplotlib. The caption is also recorded on
fig.record.captionso it survives save→reproduce round-trip.- Parameters:
fig (
Any) – The figure to add caption to.caption (
str) – The caption text (Markdown formatting is automatically stripped).figure_label (
Optional[str]) – Custom figure label (e.g. “Figure 1”). Auto-generated if None.style (
str) – Caption style: “scientific”, “nature”, “ieee”, “apa”.position (
str) – Caption position: “bottom” (default) or “top”.width_ratio (
float) – Width of caption relative to figure width.wrap_width (
int) – Character width for text wrapping.align (
str) – Caption alignment: “justify” (default), “left”, or “center”. “justify” spans the full content width with the last line left-aligned.pad_mm (
float) – Gap (mm) between the caption band and the axes / figure edge.save_to_file (
bool) – Whether to also save caption to a separate file.
- Returns:
The rendered caption text (Markdown-stripped).
- Return type:
- figrecipe.add_panel_captions(fig, axes, panel_captions, *, main_caption='', figure_label=None, panel_style='letter_bold', position='top_left', font_size='medium', offset=(0.02, 0.98))[source]
Add panel captions (A, B, C, etc.) to subplot panels.
Panel labels are rendered with Markdown-stripped text so they display cleanly in matplotlib.
- Parameters:
fig (
Any) – The figure containing panels.axes (
Any) – Axes objects for each panel.panel_captions (
Union[List[str],Dict[str,str]]) – Caption text for each panel.main_caption (
str) – Main figure caption (optional, auto-attached).figure_label (
Optional[str]) – Figure label for the main caption.panel_style (
str) – Panel label style: “letter_bold”, “letter_italic”, “number”.position (
str) – Panel label position: “top_left”, “top_right”, etc.offset (
Tuple[float,float]) – Position offset for panel labels.
- Returns:
Dictionary mapping panel labels to full caption text.
- Return type:
- figrecipe.set_manuscript_mode(on=True)[source]
Enable/disable manuscript mode process-wide.
- Return type:
- figrecipe.manuscript_mode(on=True)[source]
Context manager that sets manuscript mode for the enclosed block.
- figrecipe.is_manuscript_mode()[source]
True when manuscript mode is active (explicit flag OR env var).
- Return type:
- figrecipe.panel_label(ax, label, loc='upper left', offset=(-0.1, 1.05), fontsize=10, fontweight='bold', text_color='black', **kwargs)[source]
Place a single panel label (A, B, C, etc.) on one axes.
- Parameters:
ax (
Any) – The axes to annotate.label (
str) – The panel label text (e.g. ‘A’, ‘B’, ‘(1)’).loc (
str) – Location hint: ‘upper left’ (default), ‘upper right’, ‘lower left’, ‘lower right’.offset (
Tuple[float,float]) – (x, y) offset in axes coordinates. Default (-0.1, 1.05).fontsize (
float) – Font size in points (default 10).fontweight (
str) – Font weight (default ‘bold’).text_color (
str) – Text color (default ‘black’).**kwargs – Additional arguments passed to
ax.text().
- Returns:
The created text annotation.
- Return type:
- class figrecipe.Figz(path)[source]
Bases:
objectMulti-panel figure bundle (.fig.zip).
- Manages a ZIP file containing:
manifest.json - bundle type declaration spec.json - figure spec with panel list style.json - figure dimensions and theme panels/ - .plt.zip panel bundles
Example
>>> figz = Figz.create("Figure1.fig.zip", "Figure1") >>> figz.add_panel("A", pltz_path) >>> figz.add_panel("B", pltz_bytes)
- add_panel(label, pltz_source, position=None, size=None)[source]
Add a .plt.zip panel to this figure.
- Parameters:
- Return type:
- 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) – Plot type label stored in the panel’s spec.json (default: “image”).position (
Optional[Dict]) – Panel position e.g. {“x_mm”: 5, “y_mm”: 5}.size (
Optional[Dict]) – Panel size e.g. {“width_mm”: 80, “height_mm”: 68}.
- Return type:
- get_panel(label)[source]
Extract panel as Pltz instance (via temp file).
Note: The caller is responsible for cleaning up the temp file (accessible via the returned Pltz instance’s .path attribute).
- class figrecipe.Pltz(path)[source]
Bases:
objectSingle-plot bundle (.plt.zip).
Thin wrapper around figrecipe’s existing bundle functions: - load_bundle() - save_bundle() - reproduce_bundle()
Bundle structure (inside ZIP):
{stem}/ spec.json # WHAT to plot (semantic specification) style.json # HOW it looks (appearance settings) data.csv # Raw data recipe.yaml # Reproducible recipe exports/ figure.png
- classmethod from_png(png_bytes, path, plot_type='image', spec=None, style=None, hitmap_bytes=None, hitmap_color_map=None, data_csv=None)[source]
Create a .plt.zip bundle wrapping a pre-rendered PNG image.
Useful when a figure is rendered externally (e.g., from a gallery template) and needs to be stored as a figrecipe bundle.
- Parameters:
- Returns:
Loaded Pltz instance wrapping the saved bundle.
- Return type:
- classmethod create(path, fig)[source]
Save a RecordingFigure as a .plt.zip bundle.
- Parameters:
path (
Union[str,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:
- figrecipe.save_bundle(fig, path, dpi=None, image_formats=None, save_hitmap=False, verbose=True)[source]
Save figure as a layered bundle (ZIP format).
Bundle structure inside ZIP:
spec.json # WHAT (semantic specification) style.json # HOW (appearance settings) data.csv # DATA (immutable source data) recipe.yaml # Reproducible recipe (for fr.reproduce()) exports/ figure.png figure_hitmap.png # only if save_hitmap=True
- Parameters:
fig (RecordingFigure) – The figure to save.
path (
Union[str,Path]) – Output path (.zip will be added if not present).dpi (
Optional[int]) – DPI for exports (default from style or 300).image_formats (
Optional[list]) – Image formats to export (default: [‘png’]).save_hitmap (
bool) – Whether to save the per-pixel hitmap PNG used by the GUI editor for diff visualisation (default: False). Hitmap rendering is expensive and the typical save() caller doesn’t need it; opt in with save_hitmap=True when persisting bundles for the editor.verbose (
bool) – Whether to print status (default: True).
- Returns:
Path to saved ZIP bundle.
- Return type:
- figrecipe.load_style(style='SCITEX', dark=False, background=None)[source]
Load style configuration and apply it globally.
After calling this function, subsequent subplots() calls will automatically use the loaded style (fonts, colors, theme, etc.).
- Parameters:
style (str, Path, bool, or None) – One of: - “SCITEX” / “FIGRECIPE”: Scientific publication style (default) - “MATPLOTLIB”: Vanilla matplotlib defaults - Path to custom YAML file: “/path/to/my_style.yaml” - None or False: Unload style (reset to matplotlib defaults)
dark (bool, optional) – If True, apply dark theme transformation (default: False). Equivalent to appending “_DARK” to preset name.
background (str, optional) – Override default background color. E.g., ‘white’ for opaque figures. Sets theme.light.figure_bg and theme.light.axes_bg. Use ‘transparent’ for transparent background.
- Returns:
Style configuration with dot-notation access. Returns None if style is unloaded.
- Return type:
DotDict or None
Examples
>>> import figrecipe as fr
>>> # Load scientific style (default) >>> fr.load_style() >>> fr.load_style("SCITEX") # explicit
>>> # Load with white background (override transparent default) >>> fr.load_style("SCITEX", background='white')
>>> # Load dark theme >>> fr.load_style("SCITEX_DARK") >>> fr.load_style("SCITEX", dark=True) # equivalent
>>> # Reset to vanilla matplotlib >>> fr.load_style(None) # unload >>> fr.load_style(False) # unload >>> fr.load_style("MATPLOTLIB") # explicit vanilla
>>> # Access style values >>> style = fr.load_style("SCITEX") >>> style.axes.width_mm 40
- figrecipe.unload_style()[source]
Unload the current style and reset to matplotlib defaults.
After calling this, subsequent subplots() calls will use vanilla matplotlib behavior without FigRecipe styling.
Examples
>>> import figrecipe as fr >>> fr.load_style("SCITEX") # Apply scientific style >>> fig, ax = fr.subplots() # Styled >>> fr.unload_style() # Reset to matplotlib defaults >>> fig, ax = fr.subplots() # Vanilla matplotlib
- figrecipe.list_presets()[source]
List available style presets.
Examples
>>> import figrecipe as ps >>> ps.list_presets() ['MINIMAL', 'PRESENTATION', 'SCIENTIFIC']
- class figrecipe.Diagram(title=None, width_mm=170.0, height_mm=120.0, padding_mm=10.0, gap_mm=None)[source]
Bases:
objectBuilder for rich box-and-arrow diagrams with mm-based coordinates.
- add_box(id, title, subtitle=None, content=None, emphasis='normal', shape='rounded', x_mm=None, y_mm=None, width_mm=None, height_mm=None, fill_color=None, border_color=None, title_color=None, padding_mm=5.0, margin_mm=0.0, node_class=None, state=None, language=None, bullet=None)[source]
Add a rich text box. See BoxSpec for node_class/state/language/bullet.
- Return type:
- add_container(id, title=None, children=None, emphasis='muted', x_mm=None, y_mm=None, width_mm=None, height_mm=None, fill_color=None, border_color=None, title_loc='upper center', direction='row', container_gap_mm=8.0, container_padding_mm=8.0, equalize_heights=True, equalize_widths=True)[source]
Add a container. equalize_heights/widths: match children in row/column.
- Return type:
- add_arrow(source, target, source_anchor='auto', target_anchor='auto', source_dx=0.0, source_dy=0.0, target_dx=0.0, target_dy=0.0, label=None, style='solid', color=None, curve=0.0, linewidth_mm=0.5, label_offset_mm=None, margin_mm=None)[source]
Add an arrow connecting two boxes.
- Return type:
- add_icon(id, source, x_mm, y_mm, width_mm=8.0, height_mm=8.0, color=None, opacity=1.0)[source]
Add an icon (SVG/PNG or built-in: warning/check/cross/info/lock).
- Return type:
- validate_containers()[source]
Check every container fully encloses its declared children.
- Return type:
- auto_layout(layout='lr', margin_mm=15.0, box_size_mm=None, gap_mm=10.0, avoid_overlap=True, justify='space-between', align_items='center')[source]
Automatically position boxes. See _layout for details.
- Return type:
- _auto_box_height(box)[source]
Compute box height from content when height_mm is not specified.
- Return type:
- _finalize_canvas_size()[source]
Compute canvas height from element positions when height_mm=None.
- Return type:
- render(ax=None, auto_fix=False, auto_curve=True)[source]
Render. auto_fix=True resolves violations; auto_curve=False skips R7.
- save(path, dpi=200, save_recipe=True, save_hitmap=False, save_debug=True, watermark=False)[source]
Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.
- Return type:
- render_to_file(path, dpi=200, save_recipe=True, save_hitmap=False, save_debug=True, watermark=False)
Render, crop, and save. watermark=True adds ‘Plotted by scitex.ai’.
- Return type:
- class figrecipe.StatResult(p_value, method=None, statistic=None, statistic_name='t', dof=None, effect_size=None, effect_name='d', ci=None, ci_level=95, n=None, n_subjects=None, n_unit='', n_subjects_unit='', extras=<factory>)[source]
Bases:
objectA completed statistical test, ready to be rendered onto a figure.
Only
p_valueis structurally required — a result with no p-value is not a test result at all. The other five doctrine fields are optional at the type level but their absence is reported bymissing_fields()and warned about at render time, because “incomplete but loud” is more useful than “complete or TypeError”: a producer that genuinely cannot supply a CI (e.g. a permutation test) should still be able to render, with the gap visible.- Parameters:
p_value (
float) – The p-value of the test.method (
Optional[str]) – Human-readable test name, e.g."Welch's t-test". Rendered upright.statistic_name (
str) – Symbol for the test statistic ("t","F","U","chi2", …).dof (
Union[float,int,Sequence[float],None]) – Degrees of freedom; a scalar renderst(338), a pair rendersF(2, 57).effect_name (
str) – Symbol for the effect size ("d","r","eta2", …).ci (
Optional[Tuple[float,float]]) – Confidence interval around the estimate.ci_level (
int) – Confidence level as a percentage. Default 95.n (
Optional[int]) – Number of observations (windows / trials / samples) — lowercase n.n_subjects (
Optional[int]) – Number of subjects — capital N. Keep distinct fromn: collapsing the two hides the unit of statistical independence from the reader.n_unit (
str) – Optional units, e.g."windows"/"patients".n_subjects_unit (
str) – Optional units, e.g."windows"/"patients".
Examples
>>> result = StatResult( ... p_value=0.0004, method="Pearson correlation", ... statistic=5.1, statistic_name="t", dof=338, ... effect_size=0.42, effect_name="r", ci=(0.21, 0.60), ... n=340, n_subjects=12, ... ) >>> result.stars '***' >>> "Pearson correlation" in result.annotation() True
- missing_fields()[source]
Names of the doctrine’s six fields that this result cannot render.
- Return type:
- annotation(sep=', ', precision=3, stars=False, require_complete=True)[source]
Render the six-stat annotation string, with italic statistical symbols.
- Parameters:
sep (
str) – Separator between fields. Pass",\n"to wrap onto two lines when a panel is too narrow for one.precision (
int) – Decimal places for the p-value before it collapses to< 0.001.stars (
bool) – Prepend the significance stars on their own line. The stars are a convenience for the reader, never a substitute for the p-value — the exact number is always rendered alongside them.require_complete (
bool) – Warn (never raise) when any of the six doctrine fields is absent. Set False when the missing fields genuinely live in the caption instead.
- Returns:
e.g.
"$N$ = 12, $n$ = 340, Pearson correlation, $t$(338) = 5.10, $p$ < 0.001, $r$ = 0.42, 95% CI [0.21, 0.60]"- Return type:
- classmethod from_mapping(mapping)[source]
Build a
StatResultfrom a producer’s result dict — the adapter seam.This is how scitex-stats (or scipy, or a stored results table) hands a test result to figrecipe without either side importing the other. Common key spellings are accepted. Keys that match nothing are preserved verbatim in
extrasrather than dropped, so a producer whose schema drifts leaves a trace instead of vanishing into a silently-incomplete annotation — and the render-time completeness warning still names whatever field went missing.- Raises:
KeyError – If no p-value key is present — that is not a test result.
- Return type:
- __init__(p_value, method=None, statistic=None, statistic_name='t', dof=None, effect_size=None, effect_name='d', ci=None, ci_level=95, n=None, n_subjects=None, n_unit='', n_subjects_unit='', extras=<factory>)
- figrecipe.hints_for(figure_type)[source]
Return the hint for
figure_type, or None when there is no entry yet.None means “the registry has nothing to say”, NOT “this figure type is wrong”. Most plot types have no entry – the table is a short list of cases that came up, not a closed world. Callers must treat None as silence.
- Return type:
Optional[FigureTypeHint]
- figrecipe.known_figure_types()[source]
Figure types the registry has an entry for, aliases included.
- class figrecipe.ComparisonGeometry(*values)[source]
-
How a comparison between two conditions is drawn on this figure type.
- BRACKET_ABOVE = 'bracket_above'
A horizontal bracket spanning the two categories, above the data.
The default for categorical plots (bar, box, violin): the x positions are discrete, so a bracket has two unambiguous endpoints to span.
- INLINE_TEXT = 'inline_text'
No bracket – the statistic is written as text in the plot area.
For plots with no discrete categories to span (a scatter, a correlation): the comparison is not between two x positions, it is a property of the whole cloud, so a bracket would point at nothing.
- COLORBAR_ANNOTATION = 'colorbar_annotation'
Significance is carried by the image itself (e.g. a mask or contour).
A heatmap has no free space to run a bracket through, and a cell-by-cell test produces one statistic per cell, not one per pair – so significance is shown by marking the cells, with the method and correction named in the caption.
- figrecipe.build_spec(params)[source]
Convert a parameter dict to a figrecipe spec dict.
- Parameters:
params (
dict) – Flat parameter dict. Required key:kind. For XY plots:x,y(comma-separated floats or strings). For distributions:data,data2..data6,labels. For pie:data,labels. For heatmap:data,nrows,ncols. Optional:color,title,xlabel,ylabel,width,height,yerr.- Returns:
Figrecipe-compatible spec.
- Return type:
- Raises:
ValueError – If required parameters are missing or kind is unsupported.
- figrecipe.build_spec_from_csv(csv_path, params)[source]
Build a figrecipe spec from a CSV file path and parameters.
Uses figrecipe’s native
data_file+ column name resolution.- Parameters:
- Returns:
Figrecipe-compatible spec.
- Return type:
- Raises:
ValueError – If required parameters are missing or kind is unsupported.
- figrecipe.render_spec_to_bytes(spec, *, dpi=300, fmt='png', facecolor='white')[source]
Render a figrecipe spec dict to image bytes.
- Parameters:
- Returns:
Encoded image bytes.
- Return type:
- figrecipe.from_stats_plot_spec(spec)[source]
Create a recorded figure from a
scitex-stats.plot-specdocument.- Parameters:
spec (
Dict[str,Any]) – Stats plot spec (schemascitex-stats.plot-spec, version 1).- Returns:
Save with
figrecipe.save()to get the PNG plus editable YAML.- Return type:
Examples
>>> fig, ax = figrecipe.from_stats_plot_spec(spec) >>> figrecipe.save(fig, "ttest.png")
- figrecipe.termplot(*args)[source]
Plot y (and optional x) values in the terminal using termplotlib.
- Parameters:
*args – Either
(y,)— plotted against its indices — or(x, y, ...)where extra positional arguments are ignored.- Returns:
Displays the plot in the terminal.
- Return type:
None
- figrecipe.draw_graph(ax, G, *, layout='spring', pos=None, seed=42, node_size=100, node_color='#3498db', node_alpha=0.8, node_shape='o', node_edgecolors='white', node_linewidths=0.34, edge_width=0.34, edge_color='gray', edge_alpha=0.5, edge_style='solid', arrows=None, arrowsize=10, arrowstyle='-|>', connectionstyle='arc3,rad=0.0', labels=False, font_size=6, font_color='black', font_weight='normal', font_family='sans-serif', colormap='viridis', vmin=None, vmax=None, **layout_kwargs)[source]
Draw a NetworkX graph on matplotlib axes.
- Parameters:
ax (
Axes) – The axes to draw on.G (networkx.Graph) – The graph to draw.
layout (
str) – Layout algorithm: ‘spring’, ‘circular’, ‘kamada_kawai’, ‘shell’, ‘spectral’, ‘random’, ‘planar’, ‘spiral’, ‘hierarchical’.pos (
Optional[Dict]) – Pre-computed node positions {node: (x, y)}.seed (
int) – Random seed for layout reproducibility.node_size (
Union[str,Callable,float]) – Node sizes. Can be attribute name, callable (node, data) -> size, or scalar.node_color (
Union[str,Callable,Any]) – Node colors. Can be attribute name, callable, color name, or array.node_alpha (
float) – Node transparency.node_shape (
str) – Node marker shape.edge_width (
Union[str,Callable,float]) – Edge widths. Can be attribute name, callable (u, v, data) -> width, or scalar.edge_alpha (
float) – Edge transparency.arrows (
Optional[bool]) – Draw arrows for directed graphs. Auto-detected if None.arrowsize (
float) – Arrow head size for directed edges.labels (
Union[bool,Dict,str]) – Node labels. True for node IDs, dict for custom labels, str for attribute name.font_size (
float) – Label font size (default 6pt for scitex).colormap (
str) – Matplotlib colormap for numeric node colors.**layout_kwargs – Additional kwargs passed to layout algorithm.
- Returns:
Dictionary with ‘pos’, ‘node_collection’, ‘edge_collection’.
- Return type:
- figrecipe.smart_align(fig, panels=None)
Automatically align panels in a compact grid layout.
Works like human behavior: 1. Detect grid structure (nrows, ncols) 2. Place panels from top-left to bottom-right 3. Calculate minimum rectangle to cover all content in each row/column 4. Unify row heights and column widths 5. Use space effectively with theme margins and spacing
Uses margin and spacing values from the loaded SCITEX theme: - margins.left_mm, margins.right_mm, margins.top_mm, margins.bottom_mm - spacing.horizontal_mm, spacing.vertical_mm
- Parameters:
- Return type:
Examples
>>> import figrecipe as fr >>> fig, axes = fr.subplots(2, 2) >>> # ... add plots ... >>> fr.align_smart(fig) # Align all panels using theme settings
- figrecipe.edit(source=None, style=None, port=5050, host='127.0.0.1', open_browser=True, hot_reload=False, working_dir=None, desktop=False)
Launch interactive GUI editor for figure styling.
- Parameters:
source (RecordingFigure, str, Path, or None) – Either a live RecordingFigure object, path to a .yaml recipe file, or None to create a new blank figure.
style (str or dict, optional) – Style preset name or style dict.
port (
int) – Django server port (default: 5050).host (
str) – Host to bind server (default: “127.0.0.1”, use “0.0.0.0” for Docker).open_browser (
bool) – Whether to open browser automatically (default: True).hot_reload (
bool) – Enable hot reload (default: False).working_dir (str or Path, optional) – Working directory for file browser (default: directory containing source).
desktop (
bool) – Launch as native desktop window using pywebview (default: False). Requires: pip install figrecipe[desktop]
- Returns:
Final style overrides after editing session.
- Return type:
- figrecipe.export_editable(fig, title='', description='', include_full_paths=False, simplify_threshold=0.5)
Export a matplotlib figure with geometry data for interactive editing.
This produces a Schema v0.3 compliant dictionary with axes-local pixel coordinates for all visual elements, suitable for shape-based hit testing.
- Parameters:
fig (matplotlib.figure.Figure or scitex.plt.FigureWrapper) – The figure to export
title (
str) – Optional title for the figure metadatadescription (
str) – Optional description for the figure metadatainclude_full_paths (
bool) – If True, include full (unsimplified) paths for lines. Default False.simplify_threshold (
float) – Maximum pixel error for path simplification. Default 0.5.
- Returns:
Schema v0.3 compliant dictionary with structure: - scitex_schema: “scitex.plt.figure.editable” - scitex_schema_version: “0.3.0” - figure: {size_px, dpi, …} - axes: {ax_id: {bbox_px, …}, …} - elements: {elem_id: {geometry_px, style, …}, …} - statistics: {} (placeholder for stats integration) - data: {} (placeholder for linked data) - output: {} (rendering metadata)
- Return type:
- figrecipe.enable_svg()[source]
Manually enable SVG format for Jupyter notebook display.
Call this if figures appear pixelated in notebooks.
Examples
>>> import figrecipe as fr >>> fr.enable_svg() # Enable SVG rendering >>> fig, ax = fr.subplots() # Now renders as crisp SVG
- figrecipe.apply_style(ax, style=None)[source]
Apply mm-based styling to an axes.
- Parameters:
ax (matplotlib.axes.Axes) – Target axes to apply styling to.
style (dict or DotDict, optional) – Style configuration. If None, uses default FIGRECIPE_STYLE.
- Returns:
Trace line width in points.
- Return type:
Examples
>>> import figrecipe as ps >>> import matplotlib.pyplot as plt >>> fig, ax = plt.subplots() >>> trace_lw = ps.apply_style(ax) >>> ax.plot(x, y, lw=trace_lw)
- figrecipe.signature(image_path=None, recipe_path=None)[source]
Compute verification signature for a saved figure.
- figrecipe.caption_with_signature(caption, image_path=None, recipe_path=None, style='short')[source]
Append verification signature to a figure caption.
- Parameters:
- Returns:
Caption with appended signature.
- Return type:
Recording Wrappers (internal)
These classes back the public subplots() return value. They live
under figrecipe._wrappers rather than the top-level namespace, so
they’re documented here separately.
- class figrecipe._wrappers.RecordingFigure(fig, recorder, axes)[source]
Bases:
FigureTextMixinWrapper around matplotlib Figure that manages recording.
- Parameters:
fig (
Figure) – The underlying matplotlib figure.recorder (
Recorder) – The recorder instance.axes (
Union[RecordingAxes,List[RecordingAxes]]) – Wrapped axes objects.
Examples
>>> import figrecipe as ps >>> fig, ax = ps.subplots() >>> ax.plot([1, 2, 3], [4, 5, 6]) >>> ps.save(fig, "my_figure.yaml")
- _on_draw_finalize(event)[source]
Apply figrecipe finalize hooks once per figure lifetime.
Run-once: setting a new locator marks the canvas stale, which on the inline notebook backend triggers another draw and a SECOND inline render of the same figure. We only need to finalize once per figure — cache the flag and short-circuit on subsequent draws.
Re-entrancy guard: finalize_ticks may swap a locator, which on some backends triggers another draw and would recurse. The flag breaks the loop.
- property axes: List[List[RecordingAxes]]
Get axes as 2D array.
- property dpi
Proxy dpi to underlying figure.
Needed as a class-level descriptor so matplotlib’s _setattr_cm can do getattr(type(obj), ‘dpi’) during savefig/print_figure.
- draw(renderer)[source]
Proxy draw to underlying figure.
Needed as a class-level method so matplotlib’s _setattr_cm can do getattr(type(obj), ‘draw’) during _get_renderer.
- property flat: List[RecordingAxes]
Get flattened list of all axes.
- property record: FigureRecord
Get the figure record.
- _get_style_fontweight(key, default)[source]
Get a font WEIGHT string from the loaded style’s fonts block.
Sibling of
_get_style_fontsizefor weight-valued keys (e.g.panel_label_weight) so the weight is a style-owned field, not a hardcoded code default. Falls back todefaultwhen no style is loaded or the key is absent (older styles), so behaviour is unchanged.- Return type:
- _get_resolved_font_family()[source]
Resolve the font family LIST the active style pins on the body.
Returns the same chain the style applier gives the axis labels, ticks and title – the requested font (or its available fallback) followed by the CJK face when one exists – so the auto panel labels render in the SAME faces, glyph for glyph. A bare string here was the one path left that could not fall back for CJK, and it made the panel labels disagree with the body whenever a CJK face was installed.
Nonewhen nothing can be resolved.
- _get_theme_text_color(default='black')[source]
Get text color from loaded style’s theme settings.
- Return type:
- colorbar(mappable, ax=None, **kwargs)[source]
Add a colorbar and record it for reproduction.
axmay be a single axes OR a list/array of axes (a shared colorbar that steals space from several panels, e.g.fig.colorbar(im, ax=axes.ravel().tolist())). An explicitcax=<axes>(the colorbar is drawn into a caller-provided axes) and a standaloneScalarMappableare also handled. Every source axes is recorded inax_keys; the colorbar’s resolved geometry is captured later at SAVE time (see_capture_colorbar_geometry) so reproduction can pin it exactly. Recording logic lives in_figure_colorbarto keep this module within the per-file line budget.- Return type:
- add_panel_labels(labels=None, loc='upper left', offset=(-0.1, 1.05), fontsize=None, fontweight=None, **kwargs)[source]
Add panel labels (A, B, C, D, etc.) to multi-panel figures.
- Parameters:
labels (
Optional[List[str]]) – 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[float,float]) – (x, y) offset in axes coordinates from the corner. Default is (-0.1, 1.05) for upper left positioning.fontsize (
Optional[float]) – Font size in points. If None, uses style’s panel_label_pt or 10.fontweight (
Optional[str]) – Font weight. If None, uses the style’spanel_label_weight(SCITEX: ‘bold’), falling back to ‘bold’.**kwargs – Additional arguments passed to ax.text().
- Returns:
The matplotlib Text objects created.
- Return type:
Examples
>>> fig, axes = fr.subplots(2, 2) >>> fig.add_panel_labels() # Adds A, B, C, D >>> fig.add_panel_labels(['i', 'ii', 'iii', 'iv']) # Custom labels >>> fig.add_panel_labels(loc='upper right', offset=(1.05, 1.05))
- set_title_metadata(title)[source]
Set figure title metadata (not rendered, stored in recipe).
This is for storing a publication/reference title for the figure, separate from suptitle which is rendered on the figure.
- Parameters:
title (
str) – The figure title for publication/reference.- Returns:
Self for method chaining.
- Return type:
Examples
>>> fig, ax = fr.subplots() >>> fig.set_title_metadata("Effect of temperature on reaction rate") >>> fig.set_caption("Figure 1. Reaction rates measured at various temperatures.")
- set_caption(caption)[source]
Set figure caption metadata (not rendered, stored in recipe).
This is for storing a publication caption for the figure, typically used in scientific papers (e.g., “Fig. 1. Description…”).
- Parameters:
caption (
str) – The figure caption text.- Returns:
Self for method chaining.
- Return type:
Examples
>>> fig, ax = fr.subplots() >>> fig.set_caption("Figure 1. Temperature dependence of reaction rates.")
- set_stats(stats)[source]
Set figure-level statistics metadata (not rendered, stored in recipe).
- generate_caption(style='publication', template=None)[source]
Generate caption from stored stats. Styles: publication, brief, detailed.
- Return type:
- savefig(fname, save_recipe=True, include_data=True, data_format='csv', csv_format='separate', validate=True, validate_mse_threshold=100.0, validate_error_level='error', verbose=True, dpi=None, image_format=None, facecolor=None, save_hitmap=False, **kwargs)[source]
Save figure — equivalent to fr.save(). Same DPI, crop, recipe.
Returns (image_path, yaml_path, result).
**kwargspassed to matplotlib savefig for file-like objects.
- save_recipe(path, include_data=True, data_format='csv', csv_format='separate')[source]
Save the recording recipe to YAML.
- Parameters:
- Return type:
- class figrecipe._wrappers.RecordingAxes(ax, recorder, position=(0, 0))[source]
Bases:
RecordingAxesMethods,AxesStyleMixin,SciTexMixin,DiagramMixin,ScatterLabelsMixinWrapper around matplotlib Axes that records all calls.
This wrapper intercepts calls to plotting methods and records them for later reproduction.
- Parameters:
Examples
>>> import figrecipe as ps >>> fig, ax = ps.subplots() >>> ax.plot([1, 2, 3], [4, 5, 6], color='red', id='my_line') >>> # The call is recorded automatically
- embed(source, bounds=None, *, ax_key=None, track=True, id=None)[source]
Embed a recipe or diagram as a managed sub-panel that round-trips.
sourcemay be a recipe path, image, FigureRecord, diagram recipe, composed multi-panel recipe, or(source, ax_key).boundsis an axes-fraction[x, y, w, h](defaults to the whole axes). Returns the embedded inset RecordingAxes (or a list for a multi-panel source).
- __dir__()[source]
Return list of attributes for tab completion.
Exposes all matplotlib plotting and decoration methods alongside figrecipe’s custom methods and properties.
- _create_recording_wrapper(method_name, method)[source]
Create a wrapper function that records the call.
- _create_legend_wrapper()[source]
Build the legend() wrapper that handles SCITEX styling + figrecipe loc extensions + recording. Implementation lives in _legend_wrapper.py so this file stays focused.
- set_caption(caption)[source]
Set panel caption metadata (not rendered, stored in recipe).
- Return type:
- set_stats(stats)[source]
Set panel-level statistics metadata (not rendered, stored in recipe).
- Return type:
- _record_seaborn_call(func_name, args, kwargs, data_arrays, call_id=None)[source]
Record a seaborn plotting call.
- Return type:
- property figure
- property xaxis
- property yaxis