Publication-ready scientific plotting with Matplotlib
Project description
pubfig
Publication-ready scientific plotting with Matplotlib.
Highlights
- Publication-Style Defaults — Compact titles, cleaner legends, explicit font handling, and line weights that read more like finished paper figures.
- One Library for Common Figure Types — Statistical plots, distribution plots, dimensionality-reduction plots, evaluation curves, heatmaps, and flow plots in one API surface.
- Export Specs Without Boilerplate —
save_figure(...)directly handlessingle/doublecolumn widths, explicit output suffixes, raster DPI, and trimming. - Matplotlib-Native Workflow — Plot functions return Matplotlib
Figureobjects, so existing analysis scripts remain easy to integrate. - Explicit Layout Controls — Fine-grained control over tick direction, box/grid visibility, palettes, legends, and plot-specific layout options.
Recent News
- 2026-03-25: Panel-first Figma loop polish — panel export now defaults to title-free assets for cleaner Figma assembly,
pubfig-syncnow keeps shared title / legend placeholders off by default, and bridge/watch flows now surface bundle provenance plus the exact manual-fallback bundle path. - 2026-03-20: Local bridge automation for Figma sync — added a bridge-backed
pubfig figma bridge|sync|watchworkflow, upgradedpubfig-syncwith bridge connection mode, and enabled CLI-triggered vector import/refresh after one-time plugin connection. - 2026-03-20: Figma plugin v2 workflow polish — added
auto/hero_toprelayout presets, upgraded shared title / legend placeholders, and improved refresh behavior so manual Figma positioning is preserved more reliably unless relayout is requested.
View older changelog
- 2026-03-20: CLI + Figma plugin workflow — added
pubfig figma package|validate|inspect, introduced a single-file Figma bundle JSON format for exported panels, and scaffolded thefigma-plugin/pubfig-syncplugin for node-level import and refresh. - 2026-03-20: Figma-first panel export workflow — added
export_panel(...)andexport_panels(...)for stable subplot asset export, introduced a minimalpanel-index.jsonsync index, and documented the Codex + Figma MCP refinement path for multi-panel figures. - 2026-03-20: README alignment with pubtab style and homepage refresh — reorganized the README into a pubtab-style homepage with centered badges, language switch, highlights, dated recent news, showcase examples, and an embedded gallery hero.
- 2026-03-20: Default full install and metadata simplification — changed
pip install pubfigto install the full plotting stack by default, removed user-facing extras from the main install path, and aligned package metadata, GitHub About, and README wording. - 2026-03-19: Raincloud plot support and gallery refresh — added
raincloud(...), tuned its default styling, integrated it into the gallery, and regenerated the exported figure set. - 2026-03-19: PCA biplot and radar default updates — expanded
pca_biplot(...)with loading panel modes and group ellipses, refreshed radar defaults, unified font handling, and re-exported the gallery.
Examples
Showcase
Single-plot examples
Composite figure examples assembled in Figma
Full Gallery
Quick Start
pip install pubfig
Python Quick Start
Start with the fewest possible parameters first:
import numpy as np
import pubfig as pf
rng = np.random.default_rng(0)
means = np.array([
[0.78, 0.96],
[0.88, 1.08],
[0.84, 1.00],
], dtype=float)
data = rng.normal(loc=means[..., None], scale=0.08, size=(3, 2, 18))
data = np.clip(data, 0.0, None)
fig = pf.bar_scatter(data)
pf.save_figure(fig, "figure1.pdf")
This is enough to get your first figure out. You do not need to understand layout, export, or publication-specific parameters before the first run.
Most common next parameters
Once the minimal example works, these are usually the first parameters worth adding:
fig = pf.bar_scatter(
data,
category_names=["Condition A", "Condition B", "Condition C"],
series_names=["Ctrl", "Treatment"],
title="Bar + Scatter",
)
pf.save_figure(fig, "figure1.pdf", spec="nature", width="single")
category_names: names on the x-axisseries_names: names in the legendtitle: figure titlespec/width: journal-style export presets
Only add parameters like aspect_ratio or trim when you already know why you
need them.
Where to look up detailed parameters
If you want to understand a specific plot in more detail, start here:
help(pf.bar_scatter)
help(pf.line)
help(pf.heatmap)
You can also inspect runnable examples under examples/.
Saving PNG / SVG / PDF
save_figure(...) now expects an explicit filename suffix:
pf.save_figure(fig, "figure1.pdf")→ write PDFpf.save_figure(fig, "figure1.svg")→ write SVGpf.save_figure(fig, "figure1.png")→ write PNGpf.save_figure(fig, "figure1.jpg")→ write JPG
If you want multiple outputs, use batch_export(...) instead:
pf.batch_export(fig, "figure1", formats=("pdf", "svg", "png", "jpg"))
Plot recipes by family
These rows are the shortest useful plotting calls. When you want to export one,
reuse pf.save_figure(fig, "name.pdf") from Quick Start.
Each row assumes:
import numpy as np
import pubfig as pf
Categorical and statistical
Distribution
Trend and relationship
Matrix and multivariate
Evaluation and flow
For bar_scatter(...), significance spacing parameters now follow explicit orientation-based names:
fig = pf.bar_scatter(
data,
show_statistics=True,
significance_ns_label_offset_ratio_vertical=0.08,
significance_stars_label_offset_ratio_vertical=-0.12,
significance_label_offset_ratio_vertical=0.07,
)
pubfig → Figma
What this gives you
pubfig exports clean panel artwork, and Figma stays the place where you
assemble and finish the whole publication figure.
For day-to-day use, the main command is pubfig figma push.
Quick Start
- Install
pubfig-syncin Figma Desktop the first time: go to Plugins → Development → Import plugin from manifest..., then selectfigma-plugin/pubfig-sync/manifest.jsonfrom this repo. After that, reopen it from Plugins → Development → pubfig-sync. - Click Connect Bridge once in the plugin.
- Export your panels from Python.
- Run
pubfig figma push <panel_dir> --figure-id <id>from the terminal. - If the bridge path fails, load the written bundle in the plugin and use the manual buttons.
pubfig figma push panels --figure-id figure-01
Minimal example
Panel export now defaults to clean, title-free art so subplot titles can be
handled at the Figma assembly layer. If you explicitly want embedded panel
headers, pass include_title=True.
import numpy as np
import pubfig as pf
rng = np.random.default_rng(0)
panels = {
"a": pf.bar(rng.uniform(0.4, 0.9, size=3), category_names=["A", "B", "C"]),
"b": pf.scatter(rng.normal(size=40), rng.normal(size=40)),
}
pf.export_panels(panels, "panels", overwrite=True) # title-free art by default
pubfig figma push panels --figure-id figure-01
This writes panel assets such as a.svg, b.svg, and panel-index.json, then
uses push as the primary panel-first handoff into Figma.
How refresh works
- Keep the same
figure_idto refresh the existing figure in place. - Use a new
figure_idto import a separate figure.
FAQ / Troubleshooting
What does Connect Bridge do?
It links the open Figma plugin to your local terminal workflow so later push
commands know which live session to refresh.
What does pubfig figma push do automatically?
It is the primary agent-first command. It ensures the local bridge is available,
selects the latest connected session, writes the bundle, and then syncs or
refreshes the figure.
What is the .pubfig-figma.json file?
It is the exact Figma handoff bundle for one figure. Keep it around for manual
import, refresh, debugging, or recovery.
How do I do manual fallback?
If bridge refresh stalls, load the latest written .pubfig-figma.json bundle in
pubfig-sync, then use Import as New, Manual Refresh, or Refresh + Relayout.
When should I use pubfig figma package?
Use it as the secondary path when you only want to write a standalone
bundle without pushing immediately.
pubfig figma package panels --figure-id figure-01
Where are the advanced commands?
Use these only for finer control or debugging after the normal push path:
pubfig figma sync figure-01.pubfig-figma.json --session latest
pubfig figma watch figure-01.pubfig-figma.json --session latest
pubfig figma bridge status
If you use Codex locally, the companion skill pubfig-figma-workflow can still
orchestrate the panel export → Figma import → MCP review loop.
Plot Families
Categorical and Statistical Plots
| Function | Description | Recipe |
|---|---|---|
bar |
Simple bar chart and grouped bar chart | recipe |
bar_scatter |
Grouped bar chart with raw points and significance annotations | recipe |
stacked_bar |
Horizontal stacked bar chart | recipe |
paired |
Paired dot plot | recipe |
Distribution Plots
| Function | Description | Recipe |
|---|---|---|
box |
Box plot | recipe |
violin |
Violin plot | recipe |
strip |
Strip plot | recipe |
raincloud |
Half-violin + box + raw-point raincloud plot | recipe |
density |
Density plot with KDE | recipe |
histogram |
Histogram with optional KDE | recipe |
ridgeline |
Ridgeline plot | recipe |
Trend and Relationship Plots
| Function | Description | Recipe |
|---|---|---|
line |
Line chart with optional CI | recipe |
area |
Stacked area chart | recipe |
scatter |
Scatter plot with optional grouped workflow | recipe |
bubble |
Bubble chart | recipe |
contour2d |
2D contour plot with marginals | recipe |
radar |
Radar chart | recipe |
Matrix, Embedding, and Multivariate Plots
| Function | Description | Recipe |
|---|---|---|
heatmap |
Heatmap | recipe |
corr_matrix |
Correlation heatmap | recipe |
clustermap |
Clustered heatmap | recipe |
dimreduce |
Dimensionality-reduction scatter plot | recipe |
pca_biplot |
PCA biplot with optional loadings and group ellipses | recipe |
parallel_coordinates |
Parallel coordinates plot | recipe |
Evaluation and Flow Plots
| Function | Description | Recipe |
|---|---|---|
roc |
ROC curve with AUC | recipe |
pr_curve |
Precision-Recall curve with AP | recipe |
sankey |
Sankey diagram | recipe |
Themes, Specs, and Palettes
Built-in Themes
pubfig currently ships with these themes:
defaultnaturesciencecell
pf.set_default_theme("science")
Figure Specs
For export, save_figure(...) uses named figure specs:
naturesciencecell
Width can be specified as:
"single""double"- numeric millimeters such as
120 - string millimeters such as
"120mm"
Built-in Palettes
Built-in palettes include:
DEFAULTNATURESCIENCELANCETJAMA
from pubfig import NATURE, show_palette
show_palette(NATURE).show()
You can also fetch palettes by name:
palette = pf.get_palette("science")
palette = pf.get_palette("carto_blugrn")
These journal-style palettes are inspired palettes, not official journal standards. In pubfig, the NATURE, SCIENCE, LANCET, and JAMA cards are derived from widely used ggsci-derived community palettes rather than publisher-mandated color specifications.
Source note: ggsci documents these palettes as inspired by NPG / Nature Publishing Group, AAAS / Science, Lancet journals, and JAMA figures. See pal_npg, pal_aaas, pal_lancet, and pal_jama.
For a visual preview of all currently available palettes, see docs/palette-gallery.md.
Gallery and Examples
Most files under examples/ are either:
- runnable example scripts, or
- rendered assets used by this README and the palette docs.
If you only want the main entry points, start here:
examples/gallery.py— quick visual walkthrough of supported plotsexamples/export_gallery.py— exports the gallery tooutput_figures/examples/export_composite_showcases_panels.py— exports the panel-first composite showcases that are assembled in Figmaexamples/figma_workflow_demo.md— panel-first pubfig → Figma workflow guideexamples/generate_palette_gallery.py— regenerates the palette preview sheets and gallery docsexamples/README.md— keep/remove inventory for this folder
Advanced / secondary:
examples/export_gallery_mpl.py— focused Matplotlib export examplesfigma-plugin/pubfig-sync/— Figma plugin scaffold for panel import and refreshdocs/palette-gallery.md— visual palette gallery for built-in and Plotly-derived palettes
Development
Editable Install
pip install -e .[dev]
Run Tests
pytest
Lint
ruff check src tests examples
Regenerate Gallery
python examples/export_gallery.py
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pubfig-0.2.0.tar.gz.
File metadata
- Download URL: pubfig-0.2.0.tar.gz
- Upload date:
- Size: 6.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
887ee3f839bb24c28fbc37db6a451f28b2664e139cc4d37a7f92937f8c1af4b8
|
|
| MD5 |
c243bb901ec210e579fb3101022f2d0a
|
|
| BLAKE2b-256 |
8211cafc87e9bd45d8d655cad75c7e5918d6709d6de6f849b9443f538aefddad
|
File details
Details for the file pubfig-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pubfig-0.2.0-py3-none-any.whl
- Upload date:
- Size: 119.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c02b022ae8d70d9282f923917d49842881c17a36642812d814de9958c12f0350
|
|
| MD5 |
b5d35e492d3e6c436e2d025c95e6ee53
|
|
| BLAKE2b-256 |
c02337a67ab2189136a1bee7d8714ef393b66395c3a1cb7c87bdcd0158d45c58
|