ENH: Give control whether twinx() or twiny() overlays the main axis#31181
ENH: Give control whether twinx() or twiny() overlays the main axis#31181sanrishi wants to merge 5 commits intomatplotlib:mainfrom
Conversation
|
@rcomer @timhoffm @Archiljain Ready for review! |
|
Thanks for pushing this forward — this aligns well with the conclusions from the issue discussion. |
|
Yea! |
|
Please explain you reasoning why you choose |
|
Apologies for the oversight! I was a bit busy and lost track of in the issue discussion. Because zorder is used everywhere else in the Matplotlib source code, I mistakenly just followed that existing pattern. I will update the PR to use delta_zorder now, as I agree it makes positioning much easier for the user. |
6e8e752 to
1ab3a9f
Compare
As a general advice: You are active on many topics. Your contributions are more valuable with more quality and less volume. Take time and care to do one thing right at a time and only then move to the next topic. |
|
I consider you as my elder brother as i not have any big brother/sister who guide me, you are the one who guiding me, i remembered your every word since i joined with matplotlib
I was bit greedy i will definitely take care of that next time! Thanks for all @timhoffm |
|
Could you have a moment @timhoffm, i added a tested png after testing locally! |
PR summary
This PR addresses the ergonomics issue where twinned axes default to overlaying the main axis, obscuring the primary data unless users manually manipulate z-orders and patch visibilities.
Key Changes:
New delta_zorder Parameter: Exposed delta_zorder as a keyword-only argument in twinx() and twiny() (and updated the type stubs in _base.pyi). This allows users to easily position twins relative to the main axes (e.g., passing delta_zorder=-1 puts the twin behind the main data).
Automated Patch Visibility: Added _update_twinned_axes_patch_visibility() which evaluates the whole group of twinned axes. The group is sorted by zorder (using figure insertion order as a tie-breaker), ensuring that only the bottom-most axis has a visible background patch.
Reactive Logic: Extended set_zorder and set_frame_on in _AxesBase to trigger the patch visibility update. If a user dynamically changes the z-order or frame state of any axis in a twinned group after creation, the background visibility automatically corrects itself.
Respects frameon: The visibility logic explicitly checks ax.get_frame_on() so it does not force a background onto an axis where the user explicitly disabled the frame.
Cleanup: Removed the legacy, hardcoded patch.set_visible(False) calls in twinx() and twiny().
Documentation & Testing:
Added a new gallery example (galleries/examples/subplots_axes_and_figures/twin_axes_zorder.py) demonstrating how to plot overlapping data with a background twin.
Added comprehensive tests in lib/matplotlib/tests/test_axes.py covering default behavior, custom delta_zorder stacking, multiple twins, and dynamic visibility updates. Verified locally that regression tests pass.
Here is a quick test using ax2 = ax.twinx(delta_zorder=-1) with a semi-transparent blue line on the main axis and a solid red line on the twin. As requested in the original issue, the main axis data (blue) is correctly layered on top of the twin axis data (red), and the background patches are handling the transparency perfectly!

PR checklist