Skip to content

Fix CI breakage from matplotlib 3.11#672

Merged
ecomodeller merged 2 commits into
mainfrom
fix/wind-rose-regression-tolerance
Jun 15, 2026
Merged

Fix CI breakage from matplotlib 3.11#672
ecomodeller merged 2 commits into
mainfrom
fix/wind-rose-regression-tolerance

Conversation

@ecomodeller

@ecomodeller ecomodeller commented Jun 15, 2026

Copy link
Copy Markdown
Member

matplotlib 3.11 landed on PyPI and broke CI across every Linux job. Because uv.lock is gitignored, CI always resolves the latest matplotlib, so this hit main directly. Two distinct failures:

1. Wind rose regression test (test step)

The test (tests/regression/test_regression_rose.py) asserted byte-identical pixels against a committed baseline, conflating code-induced changes (the refactoring safety it's meant to provide) with environment-induced rendering drift. matplotlib 3.11 renders the wind rose ~22 RMS off the old baseline.

Switched to matplotlib's compare_images with an RMS tolerance of 10 — comfortably below a real layout/data regression (~30 RMS, measured) and above patch-level noise — keeping the test a refactoring tripwire that's robust to minor drift. The baseline is regenerated on 3.11, and compare_images writes a diff image on failure. matplotlib is intentionally not pinned (the unpinned matrix and the mikeio-main job track latest to catch upstream breakage early); the baseline is regenerated deliberately on a major bump.

2. mypy errors from stricter 3.11 type stubs (typecheck step)

  • _temporal_coverage.py: pass a tuple (not a list) to plt.xlim, matching the overload.
  • _wind_rose.py: the Legend loc argument is a widened str from literal assignments; targeted type: ignore, consistent with the surrounding block.

Out of scope (3.13 deprecation warnings, not current failures)

  • A pandas-internal locs deprecation (not our code).
  • apply_theta_transforms in _taylor_diagram_external.py — deferred: removing it can alter Taylor diagram rendering and there's no image regression test to guard it; warns only, doesn't break on 3.11.

The wind rose regression test asserted byte-identical pixels against a
committed baseline. This conflated code-induced changes (the refactoring
safety it was meant to provide) with environment-induced rendering drift.
matplotlib 3.11 produces ~22 RMS of sub-pixel drift, which broke the test
across all CI jobs.

Switch to matplotlib's compare_images with an RMS tolerance of 10 — well
below a real layout/data change (~30 RMS) and above patch-level noise — and
regenerate the baseline on matplotlib 3.11. compare_images also writes a
diff image on failure for inspection.
matplotlib 3.11's stricter stubs broke the typecheck CI step on two
pre-existing call sites:
- _temporal_coverage.py: pass a tuple (not a list) to plt.xlim, matching
  the overload signature.
- _wind_rose.py: the Legend 'loc' argument is a widened str from literal
  assignments; suppress with a targeted type: ignore, consistent with the
  surrounding legend block.
@ecomodeller ecomodeller changed the title Use tolerance-based image comparison for wind rose regression test Fix CI breakage from matplotlib 3.11 Jun 15, 2026
@ecomodeller ecomodeller requested a review from Copilot June 15, 2026 13:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the project to keep CI green with the newly released matplotlib 3.11 by making the wind-rose regression test robust to small rendering drift and by addressing new mypy failures triggered by stricter matplotlib stubs.

Changes:

  • Reworked the wind-rose regression test to use matplotlib.testing.compare.compare_images with an RMS tolerance instead of byte-identical pixel comparison.
  • Adjusted plotting code to satisfy updated matplotlib type stubs (tuple for plt.xlim, and a targeted type: ignore for Legend(..., loc=...)).

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/regression/test_regression_rose.py Switches regression image assertion to compare_images with tolerance and updates baseline workflow comments.
src/modelskill/plotting/_wind_rose.py Adds a mypy-targeted type: ignore[arg-type] for Legend(..., loc=...) under updated matplotlib stubs.
src/modelskill/plotting/_temporal_coverage.py Uses a tuple for plt.xlim to match the matplotlib overloads.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +55
# Compare against the baseline within a tolerance. compare_images returns
# None on success and an explanatory message on failure, writing a
# *-failed-diff.png next to img_path for inspection.
result = compare_images(baseline_path, str(img_path), tol=IMAGE_TOLERANCE)
assert result is None, result
@ecomodeller ecomodeller merged commit f7760ee into main Jun 15, 2026
12 checks passed
@ecomodeller ecomodeller deleted the fix/wind-rose-regression-tolerance branch June 15, 2026 13:38
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.

2 participants