Repository navigation
Fix twin axes ignoring navigation opt-outs (#32528) - #32544
NaumanRafay wants to merge 1 commit into
Conversation
Twin-axes siblings were added to the navigation trigger list via get_siblings() without being checked against the same predicate (_ax_filter) already applied to the primary axes. This caused twins with set_navigate(False), an unsupported can_<method>(), or an out-of-bounds event to still be triggered during pan/zoom. Fixes matplotlib#32528
|
Thank you for opening your first PR into Matplotlib! If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks. We also ask that you please finish addressing any review comments on this PR and wait for it to be merged (or closed) before opening a new one, as it can be a valuable learning experience to go through the review process. You can also join us on discourse chat for real-time discussion. For details on testing, writing docs, and our review process, please see the developer guide. We strive to be a welcoming and open project. Please follow our Code of Conduct. |
|
Hi! Please fill out the AI disclosure section (of the pull request template) with details of your AI use. Thank you! |
|
AI Disclosure AI assistance (Claude AI) was used at different points, but the core fix and tests are my own independent work. Where Claude helped: early codebase orientation (locating _start_event_axes_interaction and _ax_filter), git/GitHub workflow guidance, and reviewing my final diff/tests after I’d already written and run them. At one point a code patch that i wrote with unnecessary, overly broad changes was applied to my working copy, claude identified it, and guided me to look for other solutions. PR quality check |
|
Hi! Just following up since it’s been about a week since I opened this, happy to make any changes needed. Let me know if there’s anything I can clarify about the fix or the tests. On AI usage, as requested: I used Claude for early codebase orientation (locating _start_event_axes_interaction and _ax_filter) and general git/GitHub workflow guidance, but the fix itself and both test functions are my own work, written and verified independently. Full disclosure is in the PR description above if useful. Thanks for your time! |
Summary
Fixes #32528
Twin axes (created via
twinx()/twiny()) ignored navigation opt-outs(
set_navigate(False)) during pan/zoom. The toolbar would add twinsiblings to the navigation trigger list unconditionally, so an axes
explicitly opted out of navigation would still zoom/pan.
Root cause
In
NavigationToolbar2._start_event_axes_interaction(
lib/matplotlib/backend_bases.py), the primary axes list is filteredthrough
_ax_filter, which checksin_axes,get_navigate(), andcan_<method>()together. However, twin siblings pulled viaax._twinned_axes.get_siblings(ax)were added toaxes_to_triggerdirectly, without being passed through that same filter:
This meant a twin could still be triggered even if it had
set_navigate(False), didn't support the navigation method(
can_pan()/can_zoom()), or fell outside the event location.Fix
Pass twin siblings through the existing
_ax_filterpredicate beforeadding them, so they're held to the same standard as the primary axes:
This is a minimal, single-line change, no other logic in the function
is affected.
Testing
test_interactive_twin_navigation, which verifies that theshared axis (inherent to twins) still moves together, while the
independent axis correctly respects
set_navigate(False).test_twin_navigation_axes_filter, which verifies a twin isexcluded from
axes_to_triggerfor all three reasons_ax_filterchecks:
set_navigate(False), an unsupportedcan_<method>(), andan out-of-bounds event location.
test_backend_bases.pysuite passes (219 passed, 1 skipped —pre-existing
pgfskip unrelated to this change).mainand pass withthis fix applied.
Reproduction (from the original issue)
Before this fix, dragging a zoom rectangle would zoom both the image
(
ax2) and the line plot (ax), despiteax2.set_navigate(False).After this fix, only
axzooms.