@@ -3054,20 +3054,29 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True):
30543054 if tight is not None :
30553055 self ._tight = bool (tight )
30563056
3057+ x_shared_axes = self ._shared_axes ["x" ].get_siblings (self )
3058+ y_shared_axes = self ._shared_axes ["y" ].get_siblings (self )
3059+
30573060 x_stickies = y_stickies = np .array ([])
30583061 if self .use_sticky_edges :
30593062 if self ._xmargin and scalex and self .get_autoscalex_on ():
3060- edges = []
3061- for ax in self ._shared_axes ["x" ].get_siblings (self ):
3062- for artist in ax .get_children ():
3063- edges .extend (artist .sticky_edges .x )
3064- x_stickies = np .sort (edges )
3063+ x_sticky = []
3064+ for ax in x_shared_axes :
3065+ for artist in ax ._get_data_children ():
3066+ sticky_edges = artist ._sticky_edges
3067+ if sticky_edges is not None and sticky_edges .x :
3068+ x_sticky .extend (sticky_edges .x )
3069+ if x_sticky :
3070+ x_stickies = np .sort (x_sticky )
30653071 if self ._ymargin and scaley and self .get_autoscaley_on ():
3066- edges = []
3067- for ax in self ._shared_axes ["y" ].get_siblings (self ):
3068- for artist in ax .get_children ():
3069- edges .extend (artist .sticky_edges .y )
3070- y_stickies = np .sort (edges )
3072+ y_sticky = []
3073+ for ax in y_shared_axes :
3074+ for artist in ax ._get_data_children ():
3075+ sticky_edges = artist ._sticky_edges
3076+ if sticky_edges is not None and sticky_edges .y :
3077+ y_sticky .extend (sticky_edges .y )
3078+ if y_sticky :
3079+ y_stickies = np .sort (y_sticky )
30713080 if self .get_xscale () == 'log' :
30723081 x_stickies = x_stickies [x_stickies > 0 ]
30733082 if self .get_yscale () == 'log' :
@@ -3078,11 +3087,9 @@ def handle_single_axis(
30783087
30793088 if not (scale and axis ._get_autoscale_on ()):
30803089 return # nothing to do...
3081-
3082- shared = shared_axes .get_siblings (self )
30833090 # Base autoscaling on finite data limits when there is at least one
30843091 # finite data limit among all the shared_axes and intervals.
3085- values = [val for ax in shared
3092+ values = [val for ax in shared_axes
30863093 for val in getattr (ax .dataLim , f"interval{ name } " )
30873094 if np .isfinite (val )]
30883095 if values :
@@ -3098,20 +3105,22 @@ def handle_single_axis(
30983105 x0 , x1 = locator .nonsingular (x0 , x1 )
30993106 # Find the minimum minpos for use in the margin calculation.
31003107 minimum_minpos = min (
3101- getattr (ax .dataLim , f"minpos{ name } " ) for ax in shared )
3108+ getattr (ax .dataLim , f"minpos{ name } " ) for ax in shared_axes )
31023109
31033110 # Prevent margin addition from crossing a sticky value. A small
31043111 # tolerance must be added due to floating point issues with
31053112 # streamplot; it is defined relative to x1-x0 but has
31063113 # no absolute term (e.g. "+1e-8") to avoid issues when working with
31073114 # datasets where all values are tiny (less than 1e-8).
3108- tol = 1e-5 * abs (x1 - x0 )
3109- # Index of largest element < x0 + tol, if any.
3110- i0 = stickies .searchsorted (x0 + tol ) - 1
3111- x0bound = stickies [i0 ] if i0 != - 1 else None
3112- # Index of smallest element > x1 - tol, if any.
3113- i1 = stickies .searchsorted (x1 - tol )
3114- x1bound = stickies [i1 ] if i1 != len (stickies ) else None
3115+ x0bound = x1bound = None
3116+ if len (stickies ):
3117+ tol = 1e-5 * abs (x1 - x0 )
3118+ # Index of largest element < x0 + tol, if any.
3119+ i0 = stickies .searchsorted (x0 + tol ) - 1
3120+ x0bound = stickies [i0 ] if i0 != - 1 else None
3121+ # Index of smallest element > x1 - tol, if any.
3122+ i1 = stickies .searchsorted (x1 - tol )
3123+ x1bound = stickies [i1 ] if i1 != len (stickies ) else None
31153124
31163125 # Add the margin in figure space and then transform back, to handle
31173126 # non-linear scales.
@@ -3136,10 +3145,10 @@ def handle_single_axis(
31363145 # End of definition of internal function 'handle_single_axis'.
31373146
31383147 handle_single_axis (
3139- scalex , self . _shared_axes [ "x" ] , 'x' , self .xaxis , self ._xmargin ,
3148+ scalex , x_shared_axes , 'x' , self .xaxis , self ._xmargin ,
31403149 x_stickies , self .set_xbound )
31413150 handle_single_axis (
3142- scaley , self . _shared_axes [ "y" ] , 'y' , self .yaxis , self ._ymargin ,
3151+ scaley , y_shared_axes , 'y' , self .yaxis , self ._ymargin ,
31433152 y_stickies , self .set_ybound )
31443153
31453154 def _update_title_position (self , renderer ):
@@ -4542,6 +4551,20 @@ def drag_pan(self, button, key, x, y):
45424551 self .set_xlim (points [:, 0 ])
45434552 self .set_ylim (points [:, 1 ])
45444553
4554+ def _get_data_children (self ):
4555+ """
4556+ Return artists that represent data (plot lines, collections, images,
4557+ patches, etc.) as opposed to auxiliary artists needed to draw the
4558+ Axes itself (spines, titles, axis objects, etc.).
4559+
4560+ Data children are the artists that can contribute to autoscaling
4561+ and sticky edges.
4562+
4563+ Note: This is a preliminary definition and has not been thought
4564+ through completely. We may want to revise this later.
4565+ """
4566+ return [* self ._children , * self ._axis_map .values ()]
4567+
45454568 def get_children (self ):
45464569 # docstring inherited.
45474570 return [
0 commit comments