@@ -1049,7 +1049,7 @@ def _on_move(self, event):
1049
1049
1050
1050
x , y = event .xdata , event .ydata
1051
1051
# In case the mouse is out of bounds.
1052
- if x is None :
1052
+ if x is None or event . inaxes != self :
1053
1053
return
1054
1054
1055
1055
dx , dy = x - self .sx , y - self .sy
@@ -1083,7 +1083,7 @@ def _on_move(self, event):
1083
1083
elif self .button_pressed in self ._zoom_btn :
1084
1084
# zoom view (dragging down zooms in)
1085
1085
scale = h / (h - dy )
1086
- self ._zoom_data_limits (scale )
1086
+ self ._zoom_data_limits (scale , scale )
1087
1087
1088
1088
# Store the event coordinates for the next time through.
1089
1089
self .sx , self .sy = x , y
@@ -1104,23 +1104,20 @@ def drag_pan(self, button, key, x, y):
1104
1104
dx , dy = xdata - xdata_start , ydata - ydata_start
1105
1105
if dx == 0 and dy == 0 :
1106
1106
return
1107
-
1108
- # Now pan the view by updating the limits
1109
- w = self ._pseudo_w
1110
- h = self ._pseudo_h
1111
-
1112
- minx , maxx , miny , maxy , minz , maxz = self .get_w_lims ()
1113
- dx = 1 - ((w - dx ) / w )
1114
- dy = 1 - ((h - dy ) / h )
1115
1107
dz = 0
1108
+
1109
+ # Transform the pan into view-projected coordinates
1116
1110
u , v , n = self ._get_view_axes (self .eye )
1111
+ U , V , N = - np .array ([u , v , n ]) / self ._box_aspect * self ._dist
1112
+ dxyz_projected = dx * U + dy * V + dz * N
1117
1113
1118
- dxyz_projected = - dx * u - dy * v - dz * n
1114
+ # Calculate pan distance
1115
+ minx , maxx , miny , maxy , minz , maxz = self .get_w_lims ()
1119
1116
dxx = (maxx - minx ) * dxyz_projected [0 ]
1120
1117
dyy = (maxy - miny ) * dxyz_projected [1 ]
1121
1118
dzz = (maxz - minz ) * dxyz_projected [2 ]
1122
1119
1123
- # pan
1120
+ # Set the new axis limits
1124
1121
self .set_xlim3d (minx + dxx , maxx + dxx )
1125
1122
self .set_ylim3d (miny + dyy , maxy + dyy )
1126
1123
self .set_zlim3d (minz + dzz , maxz + dzz )
@@ -1159,11 +1156,11 @@ def _set_view_from_bbox(self, bbox, direction='in',
1159
1156
# Calculate zoom level
1160
1157
scale_x = abs ((start_x - stop_x )/ (self .bbox .max [0 ] - self .bbox .min [0 ]))
1161
1158
scale_y = abs ((start_y - stop_y )/ (self .bbox .max [1 ] - self .bbox .min [1 ]))
1162
- scale = max (scale_x , scale_y )
1163
1159
if direction == 'out' :
1164
- scale = 1 / scale
1160
+ scale_x = 1 / scale_x
1161
+ scale_y = 1 / scale_y
1165
1162
1166
- self ._zoom_data_limits (scale )
1163
+ self ._zoom_data_limits (scale_x , scale_y )
1167
1164
1168
1165
def _prepare_view_from_bbox (self , bbox , direction = 'in' ,
1169
1166
mode = None , twinx = False , twiny = False ):
@@ -1203,15 +1200,18 @@ def _prepare_view_from_bbox(self, bbox, direction='in',
1203
1200
1204
1201
return bbox
1205
1202
1206
- def _zoom_data_limits (self , scale ):
1203
+ def _zoom_data_limits (self , scale_x , scale_y , scale_z = 1 ):
1207
1204
# hmmm..this needs some help from clipping....
1205
+ u , v , n = self ._get_view_axes (self .eye )
1206
+ scale = np .abs (scale_x * u + scale_y * v + scale_z * n )
1207
+
1208
1208
minx , maxx , miny , maxy , minz , maxz = self .get_w_lims ()
1209
1209
cx = (maxx + minx )/ 2
1210
1210
cy = (maxy + miny )/ 2
1211
1211
cz = (maxz + minz )/ 2
1212
- dx = (maxx - minx )* scale / 2
1213
- dy = (maxy - miny )* scale / 2
1214
- dz = (maxz - minz )* scale / 2
1212
+ dx = (maxx - minx )* scale [ 0 ] / 2
1213
+ dy = (maxy - miny )* scale [ 1 ] / 2
1214
+ dz = (maxz - minz )* scale [ 2 ] / 2
1215
1215
self .set_xlim3d (cx - dx , cx + dx )
1216
1216
self .set_ylim3d (cy - dy , cy + dy )
1217
1217
self .set_zlim3d (cz - dz , cz + dz )
0 commit comments