@@ -3849,18 +3849,15 @@ def _set_view_from_bbox(self, bbox, direction='in',
3849
3849
twiny : bool
3850
3850
Whether this axis is twinned in the *y*-direction.
3851
3851
"""
3852
- Xmin , Xmax = self .get_xlim ()
3853
- Ymin , Ymax = self .get_ylim ()
3854
-
3855
3852
if len (bbox ) == 3 :
3856
- # Zooming code
3857
- xp , yp , scl = bbox
3853
+ Xmin , Xmax = self .get_xlim ()
3854
+ Ymin , Ymax = self .get_ylim ()
3855
+
3856
+ xp , yp , scl = bbox # Zooming code
3858
3857
3859
- # Should not happen
3860
- if scl == 0 :
3858
+ if scl == 0 : # Should not happen
3861
3859
scl = 1.
3862
3860
3863
- # direction = 'in'
3864
3861
if scl > 1 :
3865
3862
direction = 'in'
3866
3863
else :
@@ -3889,90 +3886,51 @@ def _set_view_from_bbox(self, bbox, direction='in',
3889
3886
"of length 3 or 4. Ignoring the view change." )
3890
3887
return
3891
3888
3892
- # Just grab bounding box
3893
- lastx , lasty , x , y = bbox
3894
-
3895
- # zoom to rect
3896
- inverse = self .transData .inverted ()
3897
- (lastx , lasty ), (x , y ) = inverse .transform ([(lastx , lasty ), (x , y )])
3898
-
3899
- if twinx :
3900
- x0 , x1 = Xmin , Xmax
3901
- else :
3902
- if Xmin < Xmax :
3903
- if x < lastx :
3904
- x0 , x1 = x , lastx
3905
- else :
3906
- x0 , x1 = lastx , x
3907
- if x0 < Xmin :
3908
- x0 = Xmin
3909
- if x1 > Xmax :
3910
- x1 = Xmax
3911
- else :
3912
- if x > lastx :
3913
- x0 , x1 = x , lastx
3914
- else :
3915
- x0 , x1 = lastx , x
3916
- if x0 > Xmin :
3917
- x0 = Xmin
3918
- if x1 < Xmax :
3919
- x1 = Xmax
3920
-
3921
- if twiny :
3922
- y0 , y1 = Ymin , Ymax
3923
- else :
3924
- if Ymin < Ymax :
3925
- if y < lasty :
3926
- y0 , y1 = y , lasty
3927
- else :
3928
- y0 , y1 = lasty , y
3929
- if y0 < Ymin :
3930
- y0 = Ymin
3931
- if y1 > Ymax :
3932
- y1 = Ymax
3933
- else :
3934
- if y > lasty :
3935
- y0 , y1 = y , lasty
3936
- else :
3937
- y0 , y1 = lasty , y
3938
- if y0 > Ymin :
3939
- y0 = Ymin
3940
- if y1 < Ymax :
3941
- y1 = Ymax
3942
-
3943
- if direction == 'in' :
3944
- if mode == 'x' :
3945
- self .set_xlim ((x0 , x1 ))
3946
- elif mode == 'y' :
3947
- self .set_ylim ((y0 , y1 ))
3948
- else :
3949
- self .set_xlim ((x0 , x1 ))
3950
- self .set_ylim ((y0 , y1 ))
3951
- elif direction == 'out' :
3952
- if self .get_xscale () == 'log' :
3953
- alpha = np .log (Xmax / Xmin ) / np .log (x1 / x0 )
3954
- rx1 = pow (Xmin / x0 , alpha ) * Xmin
3955
- rx2 = pow (Xmax / x0 , alpha ) * Xmin
3956
- else :
3957
- alpha = (Xmax - Xmin ) / (x1 - x0 )
3958
- rx1 = alpha * (Xmin - x0 ) + Xmin
3959
- rx2 = alpha * (Xmax - x0 ) + Xmin
3960
- if self .get_yscale () == 'log' :
3961
- alpha = np .log (Ymax / Ymin ) / np .log (y1 / y0 )
3962
- ry1 = pow (Ymin / y0 , alpha ) * Ymin
3963
- ry2 = pow (Ymax / y0 , alpha ) * Ymin
3964
- else :
3965
- alpha = (Ymax - Ymin ) / (y1 - y0 )
3966
- ry1 = alpha * (Ymin - y0 ) + Ymin
3967
- ry2 = alpha * (Ymax - y0 ) + Ymin
3968
-
3969
- if mode == 'x' :
3970
- self .set_xlim ((rx1 , rx2 ))
3971
- elif mode == 'y' :
3972
- self .set_ylim ((ry1 , ry2 ))
3973
- else :
3974
- self .set_xlim ((rx1 , rx2 ))
3975
- self .set_ylim ((ry1 , ry2 ))
3889
+ # Original limits.
3890
+ xmin0 , xmax0 = self .get_xbound ()
3891
+ ymin0 , ymax0 = self .get_ybound ()
3892
+ # The zoom box in screen coords.
3893
+ startx , starty , stopx , stopy = bbox
3894
+ # Convert to data coords.
3895
+ (startx , starty ), (stopx , stopy ) = self .transData .inverted ().transform (
3896
+ [(startx , starty ), (stopx , stopy )])
3897
+ # Clip to axes limits.
3898
+ xmin , xmax = np .clip (sorted ([startx , stopx ]), xmin0 , xmax0 )
3899
+ ymin , ymax = np .clip (sorted ([starty , stopy ]), ymin0 , ymax0 )
3900
+ # Don't double-zoom twinned axes or if zooming only the other axis.
3901
+ if twinx or mode == "y" :
3902
+ xmin , xmax = xmin0 , xmax0
3903
+ if twiny or mode == "x" :
3904
+ ymin , ymax = ymin0 , ymax0
3905
+
3906
+ if direction == "in" :
3907
+ new_xbound = xmin , xmax
3908
+ new_ybound = ymin , ymax
3909
+
3910
+ elif direction == "out" :
3911
+ x_trf = self .xaxis .get_transform ()
3912
+ sxmin0 , sxmax0 , sxmin , sxmax = x_trf .transform (
3913
+ [xmin0 , xmax0 , xmin , xmax ]) # To screen space.
3914
+ factor = (sxmax0 - sxmin0 ) / (sxmax - sxmin ) # Unzoom factor.
3915
+ # Move original bounds away by
3916
+ # (factor) x (distance between unzoom box and axes bbox).
3917
+ sxmin1 = sxmin0 - factor * (sxmin - sxmin0 )
3918
+ sxmax1 = sxmax0 + factor * (sxmax0 - sxmax )
3919
+ # And back to data space.
3920
+ new_xbound = x_trf .inverted ().transform ([sxmin1 , sxmax1 ])
3921
+
3922
+ y_trf = self .yaxis .get_transform ()
3923
+ symin0 , symax0 , symin , symax = y_trf .transform (
3924
+ [ymin0 , ymax0 , ymin , ymax ])
3925
+ factor = (symax0 - symin0 ) / (symax - symin )
3926
+ symin1 = symin0 - factor * (symin - symin0 )
3927
+ symax1 = symax0 + factor * (symax0 - symax )
3928
+ new_ybound = y_trf .inverted ().transform ([symin1 , symax1 ])
3929
+
3930
+ if not twinx and mode != "y" :
3931
+ self .set_xbound (new_xbound )
3932
+ if not twiny and mode != "x" :
3933
+ self .set_ybound (new_ybound )
3976
3934
3977
3935
def start_pan (self , x , y , button ):
3978
3936
"""
0 commit comments