@@ -2996,6 +2996,59 @@ def _zoom_pan_handler(self, event):
29962996 elif event .name == "button_release_event" :
29972997 self .release_zoom (event )
29982998
2999+ def _start_event_axes_interaction (self , event , * , method ):
3000+
3001+ def _ax_filter (ax ):
3002+ return (ax .in_axes (event ) and
3003+ ax .get_navigate () and
3004+ getattr (ax , f"can_{ method } " )()
3005+ )
3006+
3007+ def _capture_events (ax ):
3008+ f = ax .get_forward_navigation_events ()
3009+ if f == "auto" : # (capture = patch visibility)
3010+ f = not ax .patch .get_visible ()
3011+ return not f
3012+
3013+ # get all relevant axes for the event
3014+ axes = list (filter (_ax_filter , self .canvas .figure .get_axes ()))
3015+
3016+ if len (axes ) == 0 :
3017+ return []
3018+
3019+ if self ._nav_stack () is None :
3020+ self .push_current () # Set the home button to this view.
3021+
3022+ # group axes by zorder (reverse to trigger later axes first)
3023+ grps = dict ()
3024+ for ax in reversed (axes ):
3025+ grps .setdefault (ax .get_zorder (), []).append (ax )
3026+
3027+ axes_to_trigger = []
3028+ # go through zorders in reverse until we hit a capturing axes
3029+ for zorder in sorted (grps , reverse = True ):
3030+ for ax in grps [zorder ]:
3031+ axes_to_trigger .append (ax )
3032+ # NOTE: shared axes are automatically triggered, but twin-axes not!
3033+ axes_to_trigger .extend (ax ._twinned_axes .get_siblings (ax ))
3034+
3035+ if _capture_events (ax ):
3036+ break # break if we hit a capturing axes
3037+ else :
3038+ # If the inner loop finished without an explicit break,
3039+ # (e.g. no capturing axes was found) continue the
3040+ # outer loop to the next zorder.
3041+ continue
3042+
3043+ # If the inner loop was terminated with an explicit break,
3044+ # terminate the outer loop as well.
3045+ break
3046+
3047+ # avoid duplicated triggers (but keep order of list)
3048+ axes_to_trigger = list (dict .fromkeys (axes_to_trigger ))
3049+
3050+ return axes_to_trigger
3051+
29993052 def pan (self , * args ):
30003053 """
30013054 Toggle the pan/zoom tool.
@@ -3021,16 +3074,18 @@ def press_pan(self, event):
30213074 if (event .button not in [MouseButton .LEFT , MouseButton .RIGHT ]
30223075 or event .x is None or event .y is None ):
30233076 return
3024- axes = [ a for a in self . canvas . figure . get_axes ()
3025- if a . in_axes (event ) and a . get_navigate () and a . can_pan ()]
3077+
3078+ axes = self . _start_event_axes_interaction (event , method = "pan" )
30263079 if not axes :
30273080 return
3028- if self . _nav_stack () is None :
3029- self . push_current () # set the home button to this view
3081+
3082+ # call "ax.start_pan(..)" on all relevant axes of an event
30303083 for ax in axes :
30313084 ax .start_pan (event .x , event .y , event .button )
3085+
30323086 self .canvas .mpl_disconnect (self ._id_drag )
30333087 id_drag = self .canvas .mpl_connect ("motion_notify_event" , self .drag_pan )
3088+
30343089 self ._pan_info = self ._PanInfo (
30353090 button = event .button , axes = axes , cid = id_drag )
30363091
@@ -3076,21 +3131,23 @@ def press_zoom(self, event):
30763131 if (event .button not in [MouseButton .LEFT , MouseButton .RIGHT ]
30773132 or event .x is None or event .y is None ):
30783133 return
3079- axes = [ a for a in self . canvas . figure . get_axes ()
3080- if a . in_axes (event ) and a . get_navigate () and a . can_zoom ()]
3134+
3135+ axes = self . _start_event_axes_interaction (event , method = "zoom" )
30813136 if not axes :
30823137 return
3083- if self ._nav_stack () is None :
3084- self .push_current () # set the home button to this view
3138+
30853139 id_zoom = self .canvas .mpl_connect (
30863140 "motion_notify_event" , self .drag_zoom )
3141+
30873142 # A colorbar is one-dimensional, so we extend the zoom rectangle out
30883143 # to the edge of the Axes bbox in the other dimension. To do that we
30893144 # store the orientation of the colorbar for later.
3090- if hasattr (axes [0 ], "_colorbar" ):
3091- cbar = axes [0 ]._colorbar .orientation
3145+ parent_ax = axes [0 ]
3146+ if hasattr (parent_ax , "_colorbar" ):
3147+ cbar = parent_ax ._colorbar .orientation
30923148 else :
30933149 cbar = None
3150+
30943151 self ._zoom_info = self ._ZoomInfo (
30953152 direction = "in" if event .button == 1 else "out" ,
30963153 start_xy = (event .x , event .y ), axes = axes , cid = id_zoom , cbar = cbar )
0 commit comments