Fix quiver and streamplot geometry [mpl compatibility] - #339
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughQuiver and quiverkey geometry now materialize from live axes and figure transforms. Streamplot adapts native trajectories with Matplotlib-compatible filtering, arrow placement, and sampled styling. Tests and compatibility documentation cover the updated vector-field behavior. ChangesVector-field rendering
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Axes
participant QuiverRecipe
participant LiveTransforms
Axes->>QuiverRecipe: store vector and key parameters
Axes->>LiveTransforms: request current axes bbox, view, and DPI
LiveTransforms-->>QuiverRecipe: provide display-space metrics
QuiverRecipe-->>Axes: materialize segments, widths, and labels
sequenceDiagram
participant streamplot
participant kernels.streamlines
participant AdaptiveIntegrator
streamplot->>kernels.streamlines: submit normalized velocity fields
kernels.streamlines-->>streamplot: return native trajectory fragments
streamplot->>AdaptiveIntegrator: integrate when fragments fail minlength
AdaptiveIntegrator-->>streamplot: return renderable trajectories
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
spec/matplotlib/compat-changelog.md (1)
30-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueNative streamplot bullet lands under the older 2026-07-24 heading.
These trajectory/
minlength/arrow-placement changes ship with the same work as the new "Quiver display-space invariants — 2026-07-26" section above. Filing them under the earlier date makes the changelog read as if they were released then. Consider moving this bullet into the 2026-07-26 section.As per coding guidelines, "Keep the entire
spec/directory current with every relevant code, configuration, build, and release change".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@spec/matplotlib/compat-changelog.md` around lines 30 - 36, Move the “Native streamplot output” bullet from the 2026-07-24 section into the newer “Quiver display-space invariants — 2026-07-26” changelog section, preserving its text and ordering the dated entries consistently.Source: Coding guidelines
tests/pyplot/test_quiver_display_invariants.py (1)
236-291: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider covering the remaining
coordinatesbranches.
_materialize_quiver_geometrygrew four coordinate paths (axes,figure,inches,data) plus a log-scale conversion path (_quiver_render_to_raw), but onlyaxesandfigureare exercised here. A case each forcoordinates="data"/"inches"and one quiver on a log axis would lock the inversion helpers.As per path instructions, "Enforce pyplot compatibility and boundaries using the corpus and boundary tests".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/pyplot/test_quiver_display_invariants.py` around lines 236 - 291, Add tests alongside the existing quiverkey coordinate tests to cover the remaining _materialize_quiver_geometry branches: verify quiverkey placement with coordinates="data" and coordinates="inches", and add a quiver on a log-scaled axis that exercises _quiver_render_to_raw. Assert the resulting geometry against the expected transformed positions, preserving the existing axes and figure coverage.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@python/xy/pyplot/_plot_types.py`:
- Around line 5099-5121: Synchronize segment colors with geometry in the
_vector_field materialization path by applying the _quiver_valid mask returned
by _quiver_segment_arrays to the colormapped color values before repeating each
color for three segments. Preserve the existing author-time validity filtering
while ensuring arrows removed by the display-space length check contribute no
color entries.
In `@spec/matplotlib/shim-todo.md`:
- Around line 359-361: Update the checked-off quiver bullet in
spec/matplotlib/shim-todo.md to remove the claim of supported norm, z-order, and
scalar-mappable behavior, and match the streamplot bullet’s wording by
explicitly stating that these options fail loudly. Keep the other verified
quiver capabilities unchanged.
In `@tests/pyplot/test_axes_charts.py`:
- Around line 533-537: Strengthen the arrow assertion in the test around
ax._entries so it requires arrow_entry["args"][0] to contain at least one
element in addition to having an even length. Preserve the existing even-count
validation.
---
Nitpick comments:
In `@spec/matplotlib/compat-changelog.md`:
- Around line 30-36: Move the “Native streamplot output” bullet from the
2026-07-24 section into the newer “Quiver display-space invariants — 2026-07-26”
changelog section, preserving its text and ordering the dated entries
consistently.
In `@tests/pyplot/test_quiver_display_invariants.py`:
- Around line 236-291: Add tests alongside the existing quiverkey coordinate
tests to cover the remaining _materialize_quiver_geometry branches: verify
quiverkey placement with coordinates="data" and coordinates="inches", and add a
quiver on a log-scaled axis that exercises _quiver_render_to_raw. Assert the
resulting geometry against the expected transformed positions, preserving the
existing axes and figure coverage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 94b5fd9d-ed2c-4ca3-b168-44a18ffd19a5
📒 Files selected for processing (8)
python/xy/pyplot/_axes.pypython/xy/pyplot/_plot_types.pyspec/matplotlib/compat-changelog.mdspec/matplotlib/compat.mdspec/matplotlib/shim-todo.mdtests/pyplot/test_axes_charts.pytests/pyplot/test_p3_option_contracts.pytests/pyplot/test_quiver_display_invariants.py
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/pyplot/test_launch_compat.py`:
- Around line 277-281: Update the assertion logic around has_matplotlib in
test_launch_compat.py so both branches validate the sampled per-segment color
values from entry["kwargs"]["color"] using the same np.ptp(np.asarray(...)) > 0
check. Remove the no-Matplotlib key-presence-only assertion while preserving the
existing Matplotlib-gated structure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 99c0e9b0-8566-4d7f-bd60-5de561831e90
📒 Files selected for processing (1)
tests/pyplot/test_launch_compat.py
…invariants # Conflicts: # spec/matplotlib/compat-changelog.md
…o agent/quiver-display-invariants # Conflicts: # python/xy/pyplot/_axes.py
…o agent/quiver-display-invariants
Summary
This groups the selected-gallery vector-field fixes:
angles="uv"from data-transformangles="xy", including inverted axes;num_arrowsby cumulative trajectory distance;minlengthand continue automatic seeding through the bounded adaptive integrator.Why
The prior quiver path validated Matplotlib options but ignored several of them during geometry generation, used a nominal 500×370 axes, and interpreted quiver keys in data space. The native streamplot path flattened trajectories into short segments, guessed arrow counts globally, and quantized linewidths; exact arrow placement exposed that many native fragments were below Matplotlib's minimum trajectory length.
Visual comparisons
Review-only images from immutable evidence commit
2ee619a; they are not part of this PR diff.Quiver gallery
Streamplot gallery
The streamplot after image restores continuous bodies in the varying-color, varying-linewidth, multi-arrow, and masked panels instead of rendering mostly isolated arrowheads.
Verification
quiver_demo.py,quiver_simple_demo.py, andplot_streamplot.pyproduced 18 PNG and 18 SVG outputs with no execution/count failures;Remaining approximations
These differences remain visibly readable and technically bounded, but automated pixel metrics remain divergent. No local browser, native build, or full suite was run under the low-resource verification policy; GitHub CI is the final integrated gate.
Summary by CodeRabbit
angles, scaling/units, axis inversion, figure resizing, and autoscaling.