|
| 1 | +# paperplot — notes for agents |
| 2 | + |
| 3 | +Publication-correct matplotlib figures, sized/styled/preflighted per journal |
| 4 | +(APS + Nature + IEEE, plus a `talk` presentation target). Small library; keep it small. |
| 5 | + |
| 6 | +## Commands |
| 7 | +- Tests: `pytest` (Agg backend; fixtures snapshot/restore rcParams — keep that pattern). |
| 8 | +- Examples: `python examples/showcase.py` or `python examples/run_all.py` |
| 9 | + → writes PDFs to `examples/out/` and PNG proofs to `examples/out/render/` (gitignored). |
| 10 | +- Dev install: `pip install -e ".[dev]"`. Python ≥ 3.10. |
| 11 | + |
| 12 | +## Hard rules (don't break these) |
| 13 | +- **matplotlib-only core.** `numpy` + `matplotlib` are the only runtime deps. |
| 14 | + `seaborn` and `IPython` are OPTIONAL extras — import them lazily *inside* the |
| 15 | + function that needs them, behind a try/guard. Never add a top-level `import |
| 16 | + seaborn`/`IPython`. (`plots.hist_outline` has the one opt-in seaborn path.) |
| 17 | +- **Journals are data, not code.** Add/edit journal specs in |
| 18 | + `paperplot/data/journals.toml`, loaded via `registry.py` — not hardcoded. |
| 19 | +- **`__init__.py` is the public API contract.** Anything users call must be |
| 20 | + re-exported there and listed in `__all__`. Keep imports + `__all__` in sync. |
| 21 | +- **`plots.py` is a deliberately small set** of opinionated composites |
| 22 | + (hist_outline/hist_filled, data_fit_band, swatches/show_palettes). It is NOT a |
| 23 | + general plotting library — no dataframes, faceting, or grammar-of-graphics. |
| 24 | + See the "Scope amendment" note in `paperplot_DESIGN.md`. |
| 25 | +- **preflight warns, never blocks.** `save()`/`preflight()` always produce output |
| 26 | + and surface a `Report`; no raising/strict mode. |
| 27 | +- **`.mplstyle` export is an on-ramp, not the product.** `mplstyle.py` renders the |
| 28 | + *look* (rcParams) for `plt.style.use`; it cannot size/embed/preflight, so never |
| 29 | + route core sizing through it. `register_mplstyles()` mutates matplotlib's global |
| 30 | + style library — keep it opt-in; NEVER auto-register on import (silent first import). |
| 31 | + Hex colors in the file text are written without `#` (it's a comment char there). |
| 32 | + |
| 33 | +## Conventions |
| 34 | +- Default cycle is **Okabe-Ito** (colorblind-safe). Separately, the fill/stroke |
| 35 | + convention: `pp.fills()` (muted) for areas, `pp.strokes()` (bright) for lines — |
| 36 | + these are NOT colorblind-safe; don't make them the categorical default. |
| 37 | +- Sequential/diverging colormaps go through `pp.cmap(...)`, never the categorical |
| 38 | + cycle (palettes.py enforces this with a warning). |
| 39 | + |
| 40 | +## Source of truth |
| 41 | +`paperplot_DESIGN.md` records the design decisions and trade-offs — read it before |
| 42 | +changing architecture (registry/versioning, rcParams mapping, journal model). |
0 commit comments