figure-gate
figure-gate reads a matplotlib figure you have already built and tells you which publication requirements it fails. It checks colorblind-safe color, composition, and whether your type is still legible at the size the figure actually prints.
audit(fig) returns (ok, rows), 21 rows, one per check. Each row is a
(name, status, detail) triple:
ok, rows = audit(fig) # (False, [("Clipping", False, "clipped: [...]"), ...])
figure-gate verifies figures. It does not draw them, restyle them, or judge whether a figure is good. Each check forbids one named defect, so a figure that passes every row has avoided 21 named defects and nothing more.
Every threshold is a module-level constant you can read and change.
Try it
git clone https://github.com/narenp12/figure-gate && cd figure-gate
python skill/scripts/check_palette.py "#E69F00,#56B4E9,#009E73" --pairs all
python skill/scripts/check_figure.py # self-test on a deliberately broken figure
The second command prints a failing report and exits 0, because a checker that cannot fail is not a checker.
python examples/demo.py builds that figure and audits it, and
python examples/gallery.py covers the harder forms. Writing those eleven
found seven defects in the checks themselves.
Documentation
The documentation site is organised by what you came to do.
Learning. Start here if you have not run the checkers before:
- Gate your first figure — build a figure that fails, read the report, make it pass
Doing a task. Step-by-step directions for a goal you already have:
- Install figure-gate — copy the scripts, install the package, or install from conda-forge
- How-to guides — fix a failing row, gate a test suite, place at half width, attach alt text
Looking something up. What each check measures and what each function takes:
- The gates — every row, its threshold, and whether it can fail a build
- Commands — both command-line tools, their flags, and their exit codes
- Compatibility — Python and matplotlib floors, optional dependencies, import lines by version
- API reference — signatures and defaults, generated from the scripts when the site builds
Understanding why. Background, evidence, and the decisions behind the thresholds:
- How the checkers decide — the measurement model, the evidence, and what a passing run does not mean
- Figure style guide — the measurement behind each threshold, and the rules tried and reverted
- Choosing a form — the decision no styling rule rescues, built on Cleveland and McGill's ordering
- Gallery — eleven audited figures covering the forms that are hard to check
Use it with Claude Code
This repository is also a plugin marketplace, so Claude Code applies the same checks when it builds a figure for you:
/plugin marketplace add narenp12/figure-gate
Then run /plugin install figure-gate@figure-gate. The skill is invoked as
figure-gate:research-figures.
Where this sits
Prescriptive style sheets already exist and are good: SciencePlots and LovelyPlots for journal looks, tueplots and mpl_sizes for exact conference sizing. Accessibility tooling exists too: matplotalt generates alt text, Chart4Blind converts a chart image into an accessible one, and contrast reporters check colors in isolation.
Each of those acts before or beside the figure. None of them reads the built result and reports what it fails, which is the only thing figure-gate does. A style sheet and figure-gate are complementary: set your defaults with one, verify them with the other.
Stability
The public API is every name without a leading underscore in check_figure.py,
check_palette.py, and suggest_fixes.py. Below version 1.0, a minor release
may break it. Every break is named in
the changelog
under its release heading, and CI fails a pull request whose ## Unreleased
section does not name a symbol that moved.
The number of rows is not part of the contract. The shape is. For the full statement, see how the checkers decide.
Contributing
New gates are welcome at the bar the project holds itself to:
- A test proving the gate fails on a figure with that defect.
- A test proving it does not over-fire on the nearest legitimate case.
- A note naming the real failure that motivated it.
See CONTRIBUTING.md and SECURITY.md.
License
MIT. See LICENSE.
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 figure_gate-0.8.0.tar.gz.
File metadata
- Download URL: figure_gate-0.8.0.tar.gz
- Upload date:
- Size: 2.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7d3df75081a3448b64e356c003109050cda835fa92cc45af86ba807eb8ef847
|
|
| MD5 |
49c6cad8c8c694226434b20aa26d1202
|
|
| BLAKE2b-256 |
3921255eeee1da205782a13f8a54090006b386c65d5408775db42c7676b82c67
|
Provenance
The following attestation bundles were made for figure_gate-0.8.0.tar.gz:
Publisher:
release.yml on narenp12/figure-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
figure_gate-0.8.0.tar.gz -
Subject digest:
c7d3df75081a3448b64e356c003109050cda835fa92cc45af86ba807eb8ef847 - Sigstore transparency entry: 2504407787
- Sigstore integration time:
-
Permalink:
narenp12/figure-gate@0ce53461dfcc090110e380918b3fa60f55acc8c6 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/narenp12
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0ce53461dfcc090110e380918b3fa60f55acc8c6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file figure_gate-0.8.0-py3-none-any.whl.
File metadata
- Download URL: figure_gate-0.8.0-py3-none-any.whl
- Upload date:
- Size: 79.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ad08a085ce65f2e7a83dc12ec1209a68999e9a720e7d6d4f4d9f0245a43e4d5
|
|
| MD5 |
3b4bcd8476cadee02ed742bfb3ca80aa
|
|
| BLAKE2b-256 |
e945fae942d984132a9999584ff01d7808b51d5c0fd65ba04c0151f45b1b1f5a
|
Provenance
The following attestation bundles were made for figure_gate-0.8.0-py3-none-any.whl:
Publisher:
release.yml on narenp12/figure-gate
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
figure_gate-0.8.0-py3-none-any.whl -
Subject digest:
6ad08a085ce65f2e7a83dc12ec1209a68999e9a720e7d6d4f4d9f0245a43e4d5 - Sigstore transparency entry: 2504407943
- Sigstore integration time:
-
Permalink:
narenp12/figure-gate@0ce53461dfcc090110e380918b3fa60f55acc8c6 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/narenp12
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0ce53461dfcc090110e380918b3fa60f55acc8c6 -
Trigger Event:
push
-
Statement type: