Skip to content

Fix pyplot autoscale margins and bar extents#240

Draft
sselvakumaran wants to merge 13 commits into
mainfrom
agent/fix-pyplot-autoscale-margins
Draft

Fix pyplot autoscale margins and bar extents#240
sselvakumaran wants to merge 13 commits into
mainfrom
agent/fix-pyplot-autoscale-margins

Conversation

@sselvakumaran

Copy link
Copy Markdown
Contributor

Summary

  • snapshot Matplotlib's default x/y autoscale margins when each axes is created, and apply them consistently to public limits and rendered domains
  • compute bar autoscale extents from the full geometry: category width, zero or explicit baseline, and cumulative stacked endpoints
  • keep bar baselines and contour boundaries sticky while adding Matplotlib-style headroom, including log-coordinate padding
  • add regressions for line/log margins, positive/negative/mixed/stacked/horizontal/categorical bars, and bar-label headroom

Validation

  • pytest -q tests/pyplot — 623 passed, 3 skipped
  • focused autoscale/layout/reference suite — 50 passed
  • ruff check — passed
  • ruff format --check — passed
  • git diff --check — passed

The visual micro-suite also confirms line views now use the expected 5% limits and ordinary/stacked/horizontal bar labels remain inside the rendered view.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR updates pyplot autoscaling and label geometry to match Matplotlib-style margins. The main changes are:

  • Adds explicit x/y axis margin support in core chart axes and public components.
  • Snapshots pyplot rc autoscale margins when axes are created.
  • Applies consistent margin handling to public limits and rendered domains.
  • Expands bar autoscale extents using full bar geometry, baselines, and stacked endpoints.
  • Adjusts tick-label padding and bar-label alignment across browser, SVG, and raster rendering.
  • Adds tests for line/log margins, bar layouts, twin axes, singleton data, and UI label placement.

Confidence Score: 5/5

This PR appears safe to merge with low risk.

The changes are focused on autoscale range propagation and render geometry, with broad tests for the affected pyplot, core, SVG/raster, and browser paths. No verified correctness or security issues were found in the changed code.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Executed the PyTest suite for pyplot-autoscale-bar-layout validation and saved a proof log detailing the command, working directory, pytest output, timestamps, and an exit code of 0.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
python/xy/pyplot/_axes.py Snapshots rc autoscale margins, delegates render margins to core axes, and expands bar/contour autoscale extents with sticky baselines.
python/xy/_figure.py Adds axis margin support to core autorange, including explicit log-coordinate padding and singleton handling.
python/xy/components.py Exposes validated margin on public x/y axis components and forwards it into figure axis options.
python/xy/pyplot/_plot_types.py Updates bar labels to use point-scaled padding and vertical alignment for positive/negative bar geometry.
python/xy/_svg.py Adds shared tick-label offset calculation and updates SVG tick/annotation text placement.
python/xy/_raster.py Aligns raster tick-label and bottom-aligned annotation placement with SVG/browser geometry.
js/src/50_chartview.ts Adjusts browser tick-label placement to account for tick length, direction, and label padding.
tests/pyplot/test_autoscale_margin_bar_regressions.py Adds focused tests for pyplot margins, log scaling, twin axes, singleton data, bars, and bar labels.

Reviews (7): Last reviewed commit: "Remove visual comparison asset" | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 26.24%

⚠️ 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 regressed benchmark
✅ 101 untouched benchmarks
⏩ 1 skipped benchmark1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_select_lasso_message_1m 93.3 ms 126.4 ms -26.24%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing agent/fix-pyplot-autoscale-margins (06761bd) with main (960e132)

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.

Comment thread python/xy/pyplot/_axes.py
@sselvakumaran

Copy link
Copy Markdown
Contributor Author

Before / after renderings

These are the same pyplot gallery cases at the same normalized 640×480 output size. Before is the pre-PR behavior; after is this PR.

Horizontal bars — full value/category extents

Before, every bar is clipped to the fallback 0..1 x-domain. After, the data extent, category width, and label headroom are included.

Before After
Horizontal bars before Horizontal bars after

Rotated categorical bars — all categories remain in view

Before, the fallback category domain shows only two of four bars. After, all four categories and the outer half-bar widths fit.

Before After
Rotated categorical bars before Rotated categorical bars after

Positive bar labels — Matplotlib-style headroom

Before, the tallest value label crosses the top spine. After, the 5% autoscale margin keeps it inside the axes.

Before After
Positive bar labels before Positive bar labels after

The largest changes are in the plot limits and bar visibility. This PR does not fix the separate tick-label-to-tick spacing/chrome issue; that remains visible in both sets.

Copy link
Copy Markdown
Contributor Author

Follow-up on the annotation/tick-spacing review:

Previous after vs corrected after

The corrected version now:

  • uses Matplotlib's bar_label alignment model (va="bottom" for positive bars, va="top" for negative bars, centered for in-bar labels) and removes XY's extra undocumented 4 px baseline shift;
  • converts bar-label padding from points using the figure DPI;
  • measures tick-label padding from the outward end of the tick, rather than from a hard-coded spine offset, across browser, SVG, and native PNG rendering;
  • honors xtick.major.pad, ytick.major.pad, and tick_params(pad=...).

Pixel checks on the focused gallery cases:

  • bottom tick-to-label gap: 0 px → 5 px (Matplotlib: 4 px)
  • left tick-to-label gap: 4 px → 6 px (Matplotlib: 6 px)
  • positive bar label: fully inside the top spine with visible headroom

Validation: 707 passed, 3 skipped, plus a focused headless Chromium geometry test for both tick padding and bottom-aligned annotations.

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