@@ -3849,18 +3849,15 @@ def _set_view_from_bbox(self, bbox, direction='in',
38493849 twiny : bool
38503850 Whether this axis is twinned in the *y*-direction.
38513851 """
3852- Xmin , Xmax = self .get_xlim ()
3853- Ymin , Ymax = self .get_ylim ()
3854-
38553852 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
38583857
3859- # Should not happen
3860- if scl == 0 :
3858+ if scl == 0 : # Should not happen
38613859 scl = 1.
38623860
3863- # direction = 'in'
38643861 if scl > 1 :
38653862 direction = 'in'
38663863 else :
@@ -3889,90 +3886,51 @@ def _set_view_from_bbox(self, bbox, direction='in',
38893886 "of length 3 or 4. Ignoring the view change." )
38903887 return
38913888
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 )
39763934
39773935 def start_pan (self , x , y , button ):
39783936 """
0 commit comments