Skip to content

Fix pyplot stem gallery rendering [mpl compatibility] - #241

Closed
sselvakumaran wants to merge 7 commits into
mainfrom
agent/fix-matplotlib-stem-markers
Closed

Fix pyplot stem gallery rendering [mpl compatibility]#241
sselvakumaran wants to merge 7 commits into
mainfrom
agent/fix-matplotlib-stem-markers

Conversation

@sselvakumaran

Copy link
Copy Markdown
Contributor

Summary

  • include compact pyplot stem values and the baseline in autoscaling, so the official gallery example no longer falls back to a clipped 0..1 view
  • render markers and the baseline as independently mutable artists while preserving the native stem trace
  • honor basefmt, marker-only styling such as set_markerfacecolor("none"), and Matplotlib-sized default markers
  • make StemContainer.remove() remove all three exposed artists

Root cause

The pyplot extent scanner did not recognize the native stem factory. It therefore classified a populated stem axes as dataless and materialized 0..1 domains, clipping nearly all geometry. The adapter also represented the marker line, stem lines, and baseline with one shared artist and omitted the baseline rule entirely.

Matplotlib gallery reference and before/after

Official source: Matplotlib stem_plot.py

The panels below are the unmodified gallery calls. Each image shows Matplotlib 3.11, XY before this PR, and XY after this PR at the same normalized display size.

Default stem plot

Matplotlib, XY before, and XY after for the default stem plot

Custom baseline and hollow diamond markers

Matplotlib, XY before, and XY after for the customized stem plot

Validation

  • pytest -q tests/pyplot — 540 passed, 65 skipped
  • focused stem regressions and plotting-family coverage — 6 passed
  • ruff check and ruff format --check — passed
  • git diff --check — passed
  • both figures from the official Matplotlib 3.11 gallery example rendered successfully through XY's static PNG path

@codspeed-hq

codspeed-hq Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 38.16%

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

Performance Changes

Benchmark BASE HEAD Efficiency
test_first_payload_errorbar_large 770 ms 557.3 ms +38.16%

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-matplotlib-stem-markers (6e22e1c) with main (9d5865a)

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.

@sselvakumaran

Copy link
Copy Markdown
Contributor Author

stem plot in matplotlib is rendered with a red line (y=0) and with padding around it (as opposed to directly rendering x=[0,~6.25] y=[0,~2.75] it renders a box more like x=[-0.1,~6.35] y=[-0.1,~2.85]), either the API defaults are not correct and maybe it should be updated to match (mainly the stem line + being able to show that line) or the API is rejecting the customization arguments.

the diamonds are also solid not hollow in the second plot. they also seem to be relatively small (is this a problem with 2x scale?)

@sselvakumaran sselvakumaran changed the title Fix pyplot stem gallery rendering Fix pyplot stem gallery rendering [mpl compatibility] Jul 24, 2026

sselvakumaran commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the new stem-gallery feedback in 36904a3.

The missing default red baseline/padding had a separate root cause from the general pyplot margin work: core autoranging treated every trace with x0/x1/y0/y1 columns as a sticky-edge rectangle. Stem segments have those columns too, so y=0 was incorrectly pinned to the frame and the red baseline was hidden under the black axis border. Sticky zero is now limited to actual bar/histogram traces; their behavior is covered by a regression test.

Exact gallery evidence

Stem gallery before, Matplotlib 3.11 reference, and after

The columns compare the initial PR implementation (5436281), the saved Matplotlib 3.11 gallery output, and the fixed XY output (36904a3). The top row shows the default red baseline becoming visible with data padding; the bottom row shows the custom diamonds changing from solid to hollow while retaining the red y=1.1 baseline.

I reran the exact adapted Matplotlib lines_bars_and_markers/stem_plot.py example after the fix (2/2 outputs, exit 0):

  • default plot: red y=0 baseline is visible inside the frame with lower and upper padding
  • custom plot: red y=1.1 baseline remains correct and diamond markers remain hollow in the raster export
  • marker size uses Matplotlib's 6 pt default plus its 1 pt edge; the 2x static-export DPI scales the full image uniformly, so it is not shrinking the diamonds relative to the axes/text

Focused verification: 6 passed, 35 deselected; Ruff format/lint and git diff --check also pass.

This intentionally does not import PR #240's general 5% pyplot-margin change. The core currently applies its existing 3% padding here; the stem-specific bug was the incorrect zero pinning.

Copy link
Copy Markdown
Contributor Author

Follow-up on the new CodSpeed red: I investigated it and reran the benchmark workflow once. This does not appear to be a code regression from this PR.

Evidence:

  • both benchmark attempts passed all 102 benchmarks and uploaded successfully
  • CodSpeed explicitly warns that the comparison used different runtime environments
  • main's baseline ran in Azure westus3; the first PR run was centralus; the rerun was eastus (same Ubuntu image/version, different hosted runner environments)
  • the report simultaneously shows an untouched lasso-selection benchmark slowing 93.3 → 122.6 ms (-23.95%) and an untouched large-errorbar benchmark improving 769.6 → 557.3 ms (+38.09%)
  • this PR does not change the selection/channel path timed by test_select_lasso_message_1m; its timed region is channel.handle_message(...). The stem autorange change runs during figure range construction, outside that benchmark

The rerun reproduced the cross-environment classification, so changing unrelated selection code would be unjustified. Current rollup is 27 successful checks and only this 1 external CodSpeed analysis red; all required CI, Matplotlib 3.11 compatibility, docs, wheels, and the benchmark workflow itself are green. The remaining action is to acknowledge the environment-mismatched result in CodSpeed (or refresh the baseline on a comparable environment), not make a stem-code performance change.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 23f9e79c-fd30-468f-b9ba-53b7c332aa6f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-matplotlib-stem-markers

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant