@@ -90,6 +90,7 @@ def __init__(
9090 self .zz_viewLim = Bbox .unit ()
9191 self .xy_dataLim = Bbox .unit ()
9292 self .zz_dataLim = Bbox .unit ()
93+ self ._stale_viewlim_z = False
9394
9495 # inhibit autoscale_view until the axes are defined
9596 # they can't be defined until Axes.__init__ has been called
@@ -191,6 +192,24 @@ def get_zaxis(self):
191192 def _get_axis_list (self ):
192193 return super ()._get_axis_list () + (self .zaxis , )
193194
195+ def _unstale_viewLim (self ):
196+ # We should arrange to store this information once per share-group
197+ # instead of on every axis.
198+ scalex = any (ax ._stale_viewlim_x
199+ for ax in self ._shared_x_axes .get_siblings (self ))
200+ scaley = any (ax ._stale_viewlim_y
201+ for ax in self ._shared_y_axes .get_siblings (self ))
202+ scalez = any (ax ._stale_viewlim_z
203+ for ax in self ._shared_z_axes .get_siblings (self ))
204+ if scalex or scaley or scalez :
205+ for ax in self ._shared_x_axes .get_siblings (self ):
206+ ax ._stale_viewlim_x = False
207+ for ax in self ._shared_y_axes .get_siblings (self ):
208+ ax ._stale_viewlim_y = False
209+ for ax in self ._shared_z_axes .get_siblings (self ):
210+ ax ._stale_viewlim_z = False
211+ self .autoscale_view (scalex = scalex , scaley = scaley , scalez = scalez )
212+
194213 def unit_cube (self , vals = None ):
195214 minx , maxx , miny , maxy , minz , maxz = vals or self .get_w_lims ()
196215 return [(minx , miny , minz ),
@@ -378,6 +397,8 @@ def apply_aspect(self, position=None):
378397
379398 @artist .allow_rasterization
380399 def draw (self , renderer ):
400+ self ._unstale_viewLim ()
401+
381402 # draw the background patch
382403 self .patch .draw (renderer )
383404 self ._frameon = False
@@ -477,9 +498,9 @@ def _unit_change_handler(self, axis_name, event=None):
477498 self ._unit_change_handler , axis_name , event = object ())
478499 _api .check_in_list (self ._get_axis_map (), axis_name = axis_name )
479500 self .relim ()
480- self .autoscale_view (scalex = (axis_name == "x" ),
481- scaley = (axis_name == "y" ),
482- scalez = (axis_name == "z" ))
501+ self ._request_autoscale_view (scalex = (axis_name == "x" ),
502+ scaley = (axis_name == "y" ),
503+ scalez = (axis_name == "z" ))
483504
484505 def update_datalim (self , xys , ** kwargs ):
485506 pass
@@ -528,6 +549,24 @@ def set_autoscalez_on(self, b):
528549 """
529550 self ._autoscaleZon = b
530551
552+ def set_xmargin (self , m ):
553+ # docstring inherited
554+ scalez = self ._stale_viewlim_z
555+ super ().set_xmargin (m )
556+ # Superclass is 2D and will call _request_autoscale_view with defaults
557+ # for unknown Axis, which would be scalez=True, but it shouldn't be for
558+ # this call, so restore it.
559+ self ._stale_viewlim_z = scalez
560+
561+ def set_ymargin (self , m ):
562+ # docstring inherited
563+ scalez = self ._stale_viewlim_z
564+ super ().set_ymargin (m )
565+ # Superclass is 2D and will call _request_autoscale_view with defaults
566+ # for unknown Axis, which would be scalez=True, but it shouldn't be for
567+ # this call, so restore it.
568+ self ._stale_viewlim_z = scalez
569+
531570 def set_zmargin (self , m ):
532571 """
533572 Set padding of Z data limits prior to autoscaling.
@@ -542,6 +581,7 @@ def set_zmargin(self, m):
542581 if m < 0 or m > 1 :
543582 raise ValueError ("margin must be in range 0 to 1" )
544583 self ._zmargin = m
584+ self ._request_autoscale_view (scalex = False , scaley = False , scalez = True )
545585 self .stale = True
546586
547587 def margins (self , * margins , x = None , y = None , z = None , tight = True ):
@@ -639,8 +679,8 @@ def autoscale(self, enable=True, axis='both', tight=None):
639679 self ._autoscaleZon = scalez = bool (enable )
640680 else :
641681 scalez = False
642- self .autoscale_view (tight = tight , scalex = scalex , scaley = scaley ,
643- scalez = scalez )
682+ self ._request_autoscale_view (tight = tight , scalex = scalex , scaley = scaley ,
683+ scalez = scalez )
644684
645685 def auto_scale_xyz (self , X , Y , Z = None , had_data = None ):
646686 # This updates the bounding boxes as to keep a record as to what the
@@ -656,6 +696,19 @@ def auto_scale_xyz(self, X, Y, Z=None, had_data=None):
656696 # Let autoscale_view figure out how to use this data.
657697 self .autoscale_view ()
658698
699+ # API could be better, right now this is just to match the old calls to
700+ # autoscale_view() after each plotting method.
701+ def _request_autoscale_view (self , tight = None , scalex = True , scaley = True ,
702+ scalez = True ):
703+ if tight is not None :
704+ self ._tight = tight
705+ if scalex :
706+ self ._stale_viewlim_x = True # Else keep old state.
707+ if scaley :
708+ self ._stale_viewlim_y = True
709+ if scalez :
710+ self ._stale_viewlim_z = True
711+
659712 def autoscale_view (self , tight = None , scalex = True , scaley = True ,
660713 scalez = True ):
661714 """
@@ -766,6 +819,9 @@ def set_xlim3d(self, left=None, right=None, emit=True, auto=False,
766819 left , right = sorted ([left , right ], reverse = bool (reverse ))
767820 self .xy_viewLim .intervalx = (left , right )
768821
822+ # Mark viewlims as no longer stale without triggering an autoscale.
823+ for ax in self ._shared_x_axes .get_siblings (self ):
824+ ax ._stale_viewlim_x = False
769825 if auto is not None :
770826 self ._autoscaleXon = bool (auto )
771827
@@ -821,6 +877,9 @@ def set_ylim3d(self, bottom=None, top=None, emit=True, auto=False,
821877 bottom , top = top , bottom
822878 self .xy_viewLim .intervaly = (bottom , top )
823879
880+ # Mark viewlims as no longer stale without triggering an autoscale.
881+ for ax in self ._shared_y_axes .get_siblings (self ):
882+ ax ._stale_viewlim_y = False
824883 if auto is not None :
825884 self ._autoscaleYon = bool (auto )
826885
@@ -876,6 +935,9 @@ def set_zlim3d(self, bottom=None, top=None, emit=True, auto=False,
876935 bottom , top = top , bottom
877936 self .zz_viewLim .intervalx = (bottom , top )
878937
938+ # Mark viewlims as no longer stale without triggering an autoscale.
939+ for ax in self ._shared_z_axes .get_siblings (self ):
940+ ax ._stale_viewlim_z = False
879941 if auto is not None :
880942 self ._autoscaleZon = bool (auto )
881943
@@ -1346,7 +1408,8 @@ def locator_params(self, axis='both', tight=None, **kwargs):
13461408 self .yaxis .get_major_locator ().set_params (** kwargs )
13471409 if _z :
13481410 self .zaxis .get_major_locator ().set_params (** kwargs )
1349- self .autoscale_view (tight = tight , scalex = _x , scaley = _y , scalez = _z )
1411+ self ._request_autoscale_view (tight = tight , scalex = _x , scaley = _y ,
1412+ scalez = _z )
13501413
13511414 def tick_params (self , axis = 'both' , ** kwargs ):
13521415 """
0 commit comments