Skip to main content

Reproducible matplotlib wrapper with mm-precision layouts

Project description

figrecipe logo

FigRecipe

Reproducible matplotlib figures with mm-precision layouts. FigRecipe is a lightweight recording & reproduction layer for matplotlib, designed for scientific figures that must remain editable, inspectable, and reproducible.

Part of SciTeX™ – Research OS for reproducible science https://scitex.ai

PyPI version Tests License: AGPL-3.0


Why FigRecipe?

In scientific workflows, figures are often:

  • hard to reproduce once scripts change,
  • resized manually in pixels or inches,
  • impossible to partially reuse or inspect later.

FigRecipe solves this by recording plotting calls as a structured “recipe”, allowing figures to be:

  • faithfully reproduced,
  • partially re-rendered,
  • inspected for underlying data,
  • laid out in exact millimeters for publication.

Key Features

  • ✅ Drop-in replacement for matplotlib.pyplot (use figrecipe.pyplot to enable recording)
  • ✅ Automatic recording of plotting calls
  • ✅ Reproduce figures from a YAML recipe
  • ✅ Extract plotted data programmatically
  • ✅ Selective reproduction of specific plots
  • ✅ Millimeter-based layout (journal-ready)
  • ✅ Publication-quality style presets
  • ✅ Dark theme support (data colors preserved)
  • ✅ Seamless seaborn integration
  • ✅ Crop figures to content with mm margins
  • Interactive GUI editor with live preview

Examples

📓 View Demo Notebook on nbviewer (recommended)

The notebook includes side-by-side comparisons of original and reproduced figures.

Source: examples/figrecipe_demo.ipynb

Installation

pip install figrecipe

# Optional extras
pip install figrecipe[seaborn]   # seaborn + pandas support
pip install figrecipe[imaging]   # image cropping (Pillow)
pip install figrecipe[all]       # all extras

# Optional: for PDF export from notebooks (SVG → PDF)
sudo apt install inkscape  # Linux
brew install inkscape      # macOS

Requirements: Python >= 3.9

Basic Usage

Recording & Saving

import figrecipe as fr
# import figrecipe.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = fr.subplots() # or plt.subplots()
ax.plot(x, y, color='red', linewidth=2, id='sine_wave')
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')

# Save image + recipe
img_path, yaml_path, result = fr.save(fig, 'figure.png')
# → creates: figure.png + figure.yaml

Reproducing a Figure

import figrecipe as fr

fig, ax = fr.reproduce('figure.yaml')

Extracting Plotted Data

import figrecipe as fr

data = fr.extract_data('figure.yaml')
# {'sine_wave': {'x': array([...]), 'y': array([...])}}

Millimeter-Based Layout (Publication-Ready)

fig, ax = fr.subplots(
    axes_width_mm=60,
    axes_height_mm=40,
    margin_left_mm=15,
    margin_bottom_mm=12,
)

This guarantees consistent sizing across editors, exports, and journals.

Style Presets

fr.list_presets()
# ['MATPLOTLIB', 'SCITEX']

# Publication-quality preset (applied globally)
fr.load_style('SCITEX')
fig, ax = fr.subplots()

# Dark theme (UI-only, data colors preserved)
fr.load_style('SCITEX_DARK')
# or: fr.load_style('SCITEX', dark=True)

# Custom style
fr.load_style('/path/to/my_style.yaml')

See src/figrecipe/styles/presets/ for full examples.

Interactive GUI Editor

import figrecipe as fr
import numpy as np

fig, ax = fr.subplots()
ax.plot(np.sin(np.linspace(0, 10, 100)))

# Launch browser-based editor
overrides = fr.edit(fig, port=5050)

# Returns style overrides when editor is closed (Ctrl+C)
# Apply overrides to future figures or save to custom YAML

The editor provides:

  • Live preview with real-time style updates
  • Theme switching between SCITEX/MATPLOTLIB presets
  • Element selection with hover highlighting
  • Property panels for Figure, Axis, Legend, and Labels
  • Download in PNG, SVG, PDF formats
  • Export updated recipe YAML

Style Format (YAML)

# Timestamp: "2025-12-22 12:40:36 (ywatanabe)"
# File: ./src/figrecipe/styles/presets/SCITEX.yaml
# FIGRECIPE Style Preset
# ======================
# Publication-quality settings for scientific figures.
# Optimized for scientific journals with Arial font.

axes:
  width_mm: 40
  height_mm: 28
  thickness_mm: 0.2

margins:
  left_mm: 1
  right_mm: 1
  bottom_mm: 1
  top_mm: 1

spacing:
  horizontal_mm: 8
  vertical_mm: 10

fonts:
  family: "Arial"
  axis_label_pt: 7
  tick_label_pt: 7
  title_pt: 8
  suptitle_pt: 8
  legend_pt: 6
  annotation_pt: 6

padding:
  label_pt: 2.0
  tick_pt: 2.0
  title_pt: 4.0

lines:
  trace_mm: 0.2
  errorbar_mm: 0.2
  errorbar_cap_mm: 0.8

ticks:
  length_mm: 0.8
  thickness_mm: 0.2
  direction: "out"
  n_ticks: 4

markers:
  size_mm: 0.8
  scatter_mm: 0.8
  edge_width_mm: null  # None = no border (cleaner than 0)

legend:
  frameon: false         # No frame for clean look
  bg: null               # Background (null = use theme.legend_bg)
  edgecolor: null        # Frame edge color
  alpha: 1.0             # Transparency
  loc: "best"

output:
  dpi: 300
  transparent: true
  format: "pdf"

behavior:
  auto_scale_axes: true
  hide_top_spine: true
  hide_right_spine: true
  grid: false

theme:
  mode: "light"
  dark:
    figure_bg: "transparent"
    axes_bg: "transparent"
    legend_bg: "transparent"
    text: "#d4d4d4"
    spine: "#d4d4d4"
    tick: "#d4d4d4"
    grid: "#3a3a3a"
  light:
    figure_bg: "transparent"
    axes_bg: "transparent"
    legend_bg: "transparent"
    text: "black"
    spine: "black"
    tick: "black"
    grid: "#cccccc"

# SciTeX Color Palette (RGB format)
colors:
  palette:
    - [0, 128, 192]      # blue
    - [255, 70, 50]      # red
    - [20, 180, 20]      # green
    - [230, 160, 20]     # yellow
    - [200, 50, 255]     # purple
    - [20, 200, 200]     # lightblue
    - [228, 94, 50]      # orange
    - [255, 150, 200]    # pink

  # Named colors
  white: [255, 255, 255]
  black: [0, 0, 0]
  blue: [0, 128, 192]
  red: [255, 70, 50]
  pink: [255, 150, 200]
  green: [20, 180, 20]
  yellow: [230, 160, 20]
  gray: [128, 128, 128]
  grey: [128, 128, 128]
  purple: [200, 50, 255]
  lightblue: [20, 200, 200]
  brown: [128, 0, 0]
  navy: [0, 0, 100]
  orange: [228, 94, 50]

  # Semantic
  primary: [0, 128, 192]
  secondary: [255, 70, 50]
  accent: [20, 180, 20]

# EOF

API Overview

Import Description
import figrecipe.pyplot as plt Drop-in replacement of matplotlib.pyplot as plt
import figrecipe as fr Import figrecipe package
---------------------------------- ---------------------------------------------------
Function
---------------------------------- ---------------------------------------------------
fr.subplots() Create a recording-enabled figure
fr.save(fig, 'fig.png') Save image + recipe
fr.reproduce('fig.yaml') Reproduce figure from recipe
fr.extract_data('fig.yaml') Extract plotted data
fr.info('fig.yaml') Inspect recipe metadata
fr.edit(fig) Launch interactive GUI editor
fr.load_style() Load style preset (global)
fr.list_presets() List available presets
fr.crop('fig.png') Crop to content with mm margin

Positioning

FigRecipe focuses on how figures are constructed, not what they represent.

FigRecipe provides recording, reproduction, layout fidelity, and interactive editing.

Higher-level workflows (figures–tables–statistics bundle, integration with manuscript writing) are handled in:

FTS (Figure-Table-Statistics Bundle) in SciTeX Ecosystem: https://github.com/ywatanabe1989/scitex-code https://scitex.ai/vis/ https://scitex.ai/writer/

License

AGPL-3.0 See LICENSE .

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

figrecipe-0.6.0.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

figrecipe-0.6.0-py3-none-any.whl (181.6 kB view details)

Uploaded Python 3

File details

Details for the file figrecipe-0.6.0.tar.gz.

File metadata

  • Download URL: figrecipe-0.6.0.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for figrecipe-0.6.0.tar.gz
Algorithm Hash digest
SHA256 5294bea2ee7f40894c07ce8b49a2704f0bf0aafb737f16e511bb750419740735
MD5 8fddb26e71264ae8a45a7b7ea52a8b1a
BLAKE2b-256 1f37f5a10adda86fae9acea7add177d13e37853be403d4fe7bedaeb497936479

See more details on using hashes here.

File details

Details for the file figrecipe-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: figrecipe-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 181.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for figrecipe-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c0d7a9af98967efb161c3cf446485e370924fd55bf9c034995abf5ce4fae9b7
MD5 eb287b7631682c4603f97ee7a4e6220b
BLAKE2b-256 c6332d20fe14c9f64e157da99ab9a8358fa8cc277d67296e5e114b3ca79ce5c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page