Skip to content

Fix pyplot savefig output dimensions#206

Draft
sselvakumaran wants to merge 1 commit into
mainfrom
agent/fix-pyplot-savefig-scale
Draft

Fix pyplot savefig output dimensions#206
sselvakumaran wants to merge 1 commit into
mainfrom
agent/fix-pyplot-savefig-scale

Conversation

@sselvakumaran

Copy link
Copy Markdown
Contributor

What changed

  • Rasterize xy.pyplot PNG exports at one physical pixel per figsize * dpi pixel.
  • Stop doubling composed subplot canvases and bbox_inches="tight" padding.
  • Update the Matplotlib reference tests to compare equal DPI with equal DPI.
  • Add exact dimension assertions for single-panel, multi-panel, and explicit-dpi savefig paths.

Why

The pyplot shim already builds each chart at figsize * dpi, but stitch_png() passed the native renderer its separate 2x quality default and doubled composed canvases again. As a result, a Matplotlib-compatible 640x480 figure was exported as 1280x960, and point-sized artists were also rendered at the wrong effective DPI.

This change applies a 1:1 physical-pixel contract only at the pyplot compatibility boundary. The native Figure.to_png() API retains its explicit 2x default.

Impact

In the scoped 88-example static-2D Matplotlib gallery comparison:

  • exact output dimensions improve from 0/73 to 71/73 paired figures;
  • 7 figures improve from similar to the stricter near fidelity tier;
  • no figure regresses in automatic fidelity;
  • execution support remains unchanged at 52 paired / 36 unsupported.

The two remaining dimension mismatches are separate issues: matshow aspect handling (640x480 versus 480x480) and a one-pixel centimeter conversion rounding difference.

Validation

  • 536 passed, 65 skipped — complete tests/pyplot suite
  • 58 passed — focused savefig/layout/reference tests
  • Ruff lint and format checks pass
  • cargo build --release passes
  • 88-example Matplotlib gallery sweep completed

@sselvakumaran
sselvakumaran force-pushed the agent/fix-pyplot-savefig-scale branch from 1222c45 to bdb02c8 Compare July 22, 2026 17:42
@codspeed-hq

codspeed-hq Bot commented Jul 22, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by ×2.4

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 96 untouched benchmarks
⏩ 1 skipped benchmark1

Performance Changes

Benchmark BASE HEAD Efficiency
test_png_export_line_pyplot 73.9 ms 30.6 ms ×2.4

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing agent/fix-pyplot-savefig-scale (bdb02c8) with main (321da5a)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns pyplot PNG exports with Matplotlib's physical pixel dimensions. The main changes are:

  • Rasterize pyplot figures at one pixel per figsize * dpi pixel.
  • Scale composed canvases and tight-layout padding at the same rate.
  • Compare reference images at equal DPI.
  • Assert exact dimensions for regular, grid, and explicit-DPI exports.

Confidence Score: 5/5

This looks safe to merge.

No blocking issues found in the changed code.

T-Rex T-Rex Logs

What T-Rex did

  • Validated the single-panel figure size, confirming it matches 320×240 for figsize (4,3) and DPI 80.
  • Validated the stitched multi-panel figure size, confirming it matches 450×360 for figsize (5,4) and DPI 90.
  • Validated the explicit DPI override, confirming the output is 500×375 for figsize (4,3) with savefig DPI 125.
  • Both validation commands completed with exit code 0.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
python/xy/pyplot/_grid.py Changes pyplot tile rendering and composed-canvas allocation from 2× to 1× while keeping their coordinate systems aligned.
python/xy/pyplot/_mplfig.py Removes the obsolete 2× multiplier when converting tight-layout padding from inches to pixels.
tests/pyplot/test_layout_text_parity_fixes.py Updates the composed subplot expectation to the requested 640×480 output.
tests/pyplot/test_rc_color_export_contracts.py Adds exact output dimensions for regular and explicit-DPI PNG exports.
tests/pyplot/test_reference_semantics.py Compares xy and Matplotlib figures at the same DPI and physical dimensions.
tests/pyplot/test_state_and_figs.py Adds a PNG header assertion for the dimensions of composed grid exports.

Reviews (1): Last reviewed commit: "Fix pyplot savefig output dimensions" | Re-trigger Greptile

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