A small figure-making framework for research papers, built around one idea: a manuscript figure should regenerate, at its exact published size, from committed human-readable data — and every departure from the house style should carry its reason at the point where it happens.
FigKit is self-contained. Its public design rules live in specs/; the examples
exercise the same manifest, geometry, plotting, and reproducibility contracts.
There is no install step — clone and run. Every script reaches figkit through a
small sys.path header at the top of the file (copy it from the template). The
environment needs:
- Python ≥ 3.11 —
figkitreadsfigure.tomlwith the standard-librarytomllib. - numpy, scipy, matplotlib — that is all; figkit has no other dependencies.
Verify a fresh setup end to end with the self-checking test figure:
python tests/demo_figure/make_figure.pyIt builds a seven-panel figure, checks the statistics helpers against hand-computed values, measures the rendered axes against the inches its manifest declares, and confirms the framework refuses reason-less exceptions. Any failure exits non-zero.
- Read
examples/minimal_figure/— the smallest complete figure (~40 lines): one panel, one committed table, a mean ± std band, and the three rules every figure follows. - Read
examples/project_theme.pyandexamples/themed_figure/— one central project selection above an individual figure, showing palette choice and explicit canvas, layout, typography, plot, and panel-letter overrides. - Read
examples/lego_theme.py,examples/lego_figure_waves/andexamples/lego_figure_spectrum/— a small worked project: one shared design layer solving one column grid, and two figures built from it, demonstrating every panel-shape "lego" (column and row level) and the checks that prove the two figures share one grid. Seefigkit/README.md's "Building blocks: legos" section for the full system. - Run
tests/demo_figure/— the fullest worked example of the core mechanics. Its README maps each panel to the feature it demonstrates (subgrids, schematics, colorbars, geometric bands, run selection over per-run files). - Copy
figures/_template/tofigures/figure_<name>/when starting a real figure. The template is the full shape: manifest, extractor, pure plotter, caption, panels.
figures/figure_<name>/
figure.toml # geometry + selection knobs; every departure from a
# default needs a sibling <knob>_reason
extract_data.py # reduce your raw data ONCE into committed TSV tables
extracted_data/ # one row per individual observation, never a summary
extraction_log.txt # what was selected, and any shortfall vs the declared runs
make_figure.py # pure plotter: reads only the tables, derives every
# mean/band at plot time, saves at the exact declared size
CAPTION.md # hand-written caption; provenance is prose, not config
panels/ # per-panel render modules and schematic art
outputs/ # the PNG + PDF this figure's code wrote
Raw data stays outside the figures (the convention is a repo-root raw_data/,
gitignored), so a fresh clone rebuilds every figure from the committed tables alone.
All figures share one physical width (figkit.style.FIGURE_WIDTH, 183 mm by default,
appropriate for Nature and Science double-column figures); height derives from the
declared layout. A project can supply an explicit theme through config.load(...)
and style.apply_matplotlib_style(...), as shown in examples/themed_figure/.
Geometry is authored in inches in figure.toml, never in
plotting code, and never saved with bbox_inches="tight". Tables hold individual
observations; statistics are derived at plot time so the reduction is visible in
code. Any call that departs from the house layout — a grid override, a non-uniform
subgrid, a shifted panel letter, a moved frame — must say why with a reason=, and
the framework refuses the call otherwise. specs/CODE_SPECIFICATION.md holds the
full house rules; specs/scientific_coding_principles.md the principles behind them;
specs/PROJECT_DESIGN.md is the ownership rule for where a value belongs (figkit vs.
a project's design layer vs. one figure's exception) and the panel-shape promotion path.
Designed and specified by the author; implemented with Claude, with critical review by Codex.