@@ -3828,18 +3828,15 @@ def _set_view_from_bbox(self, bbox, direction='in',
3828
3828
twiny : bool
3829
3829
Whether this axis is twinned in the *y*-direction.
3830
3830
"""
3831
- Xmin , Xmax = self .get_xlim ()
3832
- Ymin , Ymax = self .get_ylim ()
3833
-
3834
3831
if len (bbox ) == 3 :
3835
- # Zooming code
3836
- xp , yp , scl = bbox
3832
+ Xmin , Xmax = self .get_xlim ()
3833
+ Ymin , Ymax = self .get_ylim ()
3834
+
3835
+ xp , yp , scl = bbox # Zooming code
3837
3836
3838
- # Should not happen
3839
- if scl == 0 :
3837
+ if scl == 0 : # Should not happen
3840
3838
scl = 1.
3841
3839
3842
- # direction = 'in'
3843
3840
if scl > 1 :
3844
3841
direction = 'in'
3845
3842
else :
@@ -3868,90 +3865,51 @@ def _set_view_from_bbox(self, bbox, direction='in',
3868
3865
"of length 3 or 4. Ignoring the view change." )
3869
3866
return
3870
3867
3871
- # Just grab bounding box
3872
- lastx , lasty , x , y = bbox
3873
-
3874
- # zoom to rect
3875
- inverse = self .transData .inverted ()
3876
- (lastx , lasty ), (x , y ) = inverse .transform ([(lastx , lasty ), (x , y )])
3877
-
3878
- if twinx :
3879
- x0 , x1 = Xmin , Xmax
3880
- else :
3881
- if Xmin < Xmax :
3882
- if x < lastx :
3883
- x0 , x1 = x , lastx
3884
- else :
3885
- x0 , x1 = lastx , x
3886
- if x0 < Xmin :
3887
- x0 = Xmin
3888
- if x1 > Xmax :
3889
- x1 = Xmax
3890
- else :
3891
- if x > lastx :
3892
- x0 , x1 = x , lastx
3893
- else :
3894
- x0 , x1 = lastx , x
3895
- if x0 > Xmin :
3896
- x0 = Xmin
3897
- if x1 < Xmax :
3898
- x1 = Xmax
3899
-
3900
- if twiny :
3901
- y0 , y1 = Ymin , Ymax
3902
- else :
3903
- if Ymin < Ymax :
3904
- if y < lasty :
3905
- y0 , y1 = y , lasty
3906
- else :
3907
- y0 , y1 = lasty , y
3908
- if y0 < Ymin :
3909
- y0 = Ymin
3910
- if y1 > Ymax :
3911
- y1 = Ymax
3912
- else :
3913
- if y > lasty :
3914
- y0 , y1 = y , lasty
3915
- else :
3916
- y0 , y1 = lasty , y
3917
- if y0 > Ymin :
3918
- y0 = Ymin
3919
- if y1 < Ymax :
3920
- y1 = Ymax
3921
-
3922
- if direction == 'in' :
3923
- if mode == 'x' :
3924
- self .set_xlim ((x0 , x1 ))
3925
- elif mode == 'y' :
3926
- self .set_ylim ((y0 , y1 ))
3927
- else :
3928
- self .set_xlim ((x0 , x1 ))
3929
- self .set_ylim ((y0 , y1 ))
3930
- elif direction == 'out' :
3931
- if self .get_xscale () == 'log' :
3932
- alpha = np .log (Xmax / Xmin ) / np .log (x1 / x0 )
3933
- rx1 = pow (Xmin / x0 , alpha ) * Xmin
3934
- rx2 = pow (Xmax / x0 , alpha ) * Xmin
3935
- else :
3936
- alpha = (Xmax - Xmin ) / (x1 - x0 )
3937
- rx1 = alpha * (Xmin - x0 ) + Xmin
3938
- rx2 = alpha * (Xmax - x0 ) + Xmin
3939
- if self .get_yscale () == 'log' :
3940
- alpha = np .log (Ymax / Ymin ) / np .log (y1 / y0 )
3941
- ry1 = pow (Ymin / y0 , alpha ) * Ymin
3942
- ry2 = pow (Ymax / y0 , alpha ) * Ymin
3943
- else :
3944
- alpha = (Ymax - Ymin ) / (y1 - y0 )
3945
- ry1 = alpha * (Ymin - y0 ) + Ymin
3946
- ry2 = alpha * (Ymax - y0 ) + Ymin
3947
-
3948
- if mode == 'x' :
3949
- self .set_xlim ((rx1 , rx2 ))
3950
- elif mode == 'y' :
3951
- self .set_ylim ((ry1 , ry2 ))
3952
- else :
3953
- self .set_xlim ((rx1 , rx2 ))
3954
- self .set_ylim ((ry1 , ry2 ))
3868
+ # Original limits.
3869
+ xmin0 , xmax0 = self .get_xbound ()
3870
+ ymin0 , ymax0 = self .get_ybound ()
3871
+ # The zoom box in screen coords.
3872
+ startx , starty , stopx , stopy = bbox
3873
+ # Convert to data coords.
3874
+ (startx , starty ), (stopx , stopy ) = self .transData .inverted ().transform (
3875
+ [(startx , starty ), (stopx , stopy )])
3876
+ # Clip to axes limits.
3877
+ xmin , xmax = np .clip (sorted ([startx , stopx ]), xmin0 , xmax0 )
3878
+ ymin , ymax = np .clip (sorted ([starty , stopy ]), ymin0 , ymax0 )
3879
+ # Don't double-zoom twinned axes or if zooming only the other axis.
3880
+ if twinx or mode == "y" :
3881
+ xmin , xmax = xmin0 , xmax0
3882
+ if twiny or mode == "x" :
3883
+ ymin , ymax = ymin0 , ymax0
3884
+
3885
+ if direction == "in" :
3886
+ new_xbound = xmin , xmax
3887
+ new_ybound = ymin , ymax
3888
+
3889
+ elif direction == "out" :
3890
+ x_trf = self .xaxis .get_transform ()
3891
+ sxmin0 , sxmax0 , sxmin , sxmax = x_trf .transform (
3892
+ [xmin0 , xmax0 , xmin , xmax ]) # To screen space.
3893
+ factor = (sxmax0 - sxmin0 ) / (sxmax - sxmin ) # Unzoom factor.
3894
+ # Move original bounds away by
3895
+ # (factor) x (distance between unzoom box and axes bbox).
3896
+ sxmin1 = sxmin0 - factor * (sxmin - sxmin0 )
3897
+ sxmax1 = sxmax0 + factor * (sxmax0 - sxmax )
3898
+ # And back to data space.
3899
+ new_xbound = x_trf .inverted ().transform ([sxmin1 , sxmax1 ])
3900
+
3901
+ y_trf = self .yaxis .get_transform ()
3902
+ symin0 , symax0 , symin , symax = y_trf .transform (
3903
+ [ymin0 , ymax0 , ymin , ymax ])
3904
+ factor = (symax0 - symin0 ) / (symax - symin )
3905
+ symin1 = symin0 - factor * (symin - symin0 )
3906
+ symax1 = symax0 + factor * (symax0 - symax )
3907
+ new_ybound = y_trf .inverted ().transform ([symin1 , symax1 ])
3908
+
3909
+ if not twinx and mode != "y" :
3910
+ self .set_xbound (new_xbound )
3911
+ if not twiny and mode != "x" :
3912
+ self .set_ybound (new_ybound )
3955
3913
3956
3914
def start_pan (self , x , y , button ):
3957
3915
"""
0 commit comments