Skip to content

Add a deterministic figure layout check (scripts/figcheck.py) - #41

Merged
annefou merged 1 commit into
mainfrom
feat/figure-layout-check
Oct 11, 2026
Merged

annefou merged 1 commit into
mainfrom
feat/figure-layout-check

Conversation

@annefou

@annefou annefou commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

What

scripts/figcheck.py checks a rendered matplotlib figure and raises when:

  • two visible text labels overlap or sit closer than 3 pt (titles, axis labels, tick labels in view, annotations, legend entries);
  • a legend covers a plotted data point or line vertex.

Because assert_layout(fig) raises, a crowded figure fails the notebook and the Snakemake rule (locally and in CI) instead of reaching the Jupyter Book. A helper, spread_labels(ax, [(x, y, text), ...]), places direct labels at the end of lines with the minimum separation.

Changes

File Change
scripts/figcheck.py new: layout_problems, assert_layout, spread_labels
tests/test_figcheck.py new: 7 tests (clean figure passes; overlapping annotations, colliding ticks, legend over data are flagged; ticks outside the view are ignored; spread_labels separates close labels)
notebooks/04_figures.py the scaffold imports the check and calls assert_layout(fig) before savefig
docs/cicd-conventions.md new section "Check figure layout in code, not by eye"

The template's full test suite passes (178 tests).

Why

Figure problems (labels on top of each other, a legend hiding data, direct labels running into the next panel) do not fail a pipeline today; they are found by eye or not at all. Developed in annefou/logrono-flood-adaptation-scenarios, where it caught all three in real figures.

Scope

Layout only. It does not judge whether a chart is the right one or whether its colours are distinguishable for colour-vision deficiencies: still look at the output.

🤖 Generated with Claude Code

assert_layout(fig) raises when two visible text labels overlap or sit
closer than 3 pt, or when a legend covers a data point, so a crowded figure
fails the notebook and the pipeline instead of reaching the Jupyter Book.
spread_labels() places direct line labels with the minimum separation.
The 04_figures scaffold calls the check before savefig; cicd-conventions
documents it. Tests in tests/test_figcheck.py.

Developed in annefou/logrono-flood-adaptation-scenarios, where it caught a
legend over data, crowded line labels and labels running into the next panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@annefou
annefou merged commit 158ca53 into main Oct 11, 2026
3 checks passed
@annefou
annefou deleted the feat/figure-layout-check branch October 11, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant