8000 Merge pull request #16831 from anntzer/zoom · matplotlib/matplotlib@74e7684 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 74e7684

Browse files
authored
Merge pull request #16831 from anntzer/zoom
Simplify interactive zoom handling.
2 parents eb0917b + c8d5bcd commit 74e7684

File tree

1 file changed

+44
-69
lines changed

1 file changed

+44
-69
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 44 additions & 69 deletions
3036
Original file line numberDiff line numberDiff line change
@@ -2722,7 +2722,7 @@ def __init__(self, canvas):
27222722
self._init_toolbar()
27232723
self._id_drag = self.canvas.mpl_connect(
27242724
'motion_notify_event', self.mouse_move)
2725-
self._id_zoom = None
2725+
self._zoom_info = None
27262726

27272727
self._button_pressed = None # determined by button pressed at start
27282728

@@ -2932,37 +2932,24 @@ def press_pan(self, event):
29322932

29332933
def press_zoom(self, event):
29342934
"""Callback for mouse button press in zoom to rect mode."""
2935-
# If we're already in the middle of a zoom, pressing another
2936-
# button works to "cancel"
2937-
if self._id_zoom is not None:
2938-
self.canvas.mpl_disconnect(self._id_zoom)
2939-
self.release(event)
2940-
self.draw()
2941-
self._xypress = None
2942-
self._button_pressed = None
2943-
self._id_zoom = None
2935+
if event.button not in [1, 3]:
29442936
return
2945-
2946-
if event.button in [1, 3]:
2947-
self._button_pressed = event.button
2948-
else:
2949-
self._button_pressed = None
2937+
if event.x is None or event.y is None:
2938+
return
2939+
axes = [a for a in self.canvas.figure.get_axes()
2940+
if a.in_axes(event) and a.get_navigate() and a.can_zoom()]
2941+
if not axes:
29502942
return
2951-
29522943
if self._nav_stack() is None:
2953-
# set the home button to this view
2954-
self.push_current()
2955-
2956-
x, y = event.x, event.y
2957-
self._xypress = []
2958-
for a in self.canvas.figure.get_axes():
2959-
if (x is not None and y is not None and a.in_axes(event) and
2960-
a.get_navigate() and a.can_zoom()):
2961-
self._xypress.append((x, y, a))
2962-
2963-
self._id_zoom = self.canvas.mpl_connect(
2964-
'motion_notify_event', self.drag_zoom)
2965-
2944+
self.push_current() # set the home button to this view
2945+
id_zoom = self.canvas.mpl_connect(
2946+
"motion_notify_event", self.drag_zoom)
2947+
self._zoom_info = {
2948+
"direction": "in" if event.button == 1 else "out",
2949+
"start_xy": (event.x, event.y),
2950+
"axes": axes,
2951+
"cid": id_zoom,
2952+
}
29662953
self.press(event)
29672954

29682955
def push_current(self):
@@ -3007,65 +2994,53 @@ def drag_pan(self, event):
30072994

30082995
def drag_zoom(self, event):
30092996
"""Callback for dragging in zoom mode."""
3010-
if self._xypress:
3011-
x, y = event.x, event.y
3012-
lastx, lasty, a = self._xypress[0]
3013-
(x1, y1), (x2, y2) = np.clip(
3014-
[[lastx, lasty], [x, y]], a.bbox.min, a.bbox.max)
3015-
if event.key == "x":
3016-
y1, y2 = a.bbox.intervaly
3017-
elif event.key == "y":
3018-
x1, x2 = a.bbox.intervalx
3019-
self.draw_rubberband(event, x1, y1, x2, y2)
2997+
start_xy = self._zoom_info["start_xy"]
2998+
ax = self._zoom_info["axes"][0]
2999+
(x1, y1), (x2, y2) = np.clip(
3000+
[start_xy, [event.x, event.y]], ax.bbox.min, ax.bbox.max)
3001+
if event.key == "x":
3002+
y1, y2 = ax.bbox.intervaly
3003+
elif event.key == "y":
3004+
x1, x2 = ax.bbox.intervalx
3005+
self.draw_rubberband(event, x1, y1, x2, y2)
30203006

30213007
def release_zoom(self, event):
30223008
"""Callback for mouse button release in zoom to rect mode."""
3023-
if self._id_zoom is not None:
3024-
self.canvas.mpl_disconnect(self._id_zoom)
3025-
self._id_zoom = None
3009+
if self._zoom_info is None:
3010+
return
30263011

3012+
# We don't check the event button here, so that zooms can be cancelled
3013+
# by (pressing and) releasing another mouse button.
3014+
self.canvas.mpl_disconnect(self._zoom_info["cid"])
30273015
self.remove_rubberband()
30283016

3029-
if not self._xypress:
3030-
return
3031-
3032-
last_a = []
3017+
start_x, start_y = self._zoom_info["start_xy"]
30333018

3034-
for lastx, lasty, a in self._xypress:
3019+
for i, ax in enumerate(self._zoom_info["axes"]):
30353020
x, y = event.x, event.y
3021
# ignore singular clicks - 5 pixels is a threshold
30373022
# allows the user to "cancel" a zoom action
30383023
# by zooming by less than 5 pixels
3039-
if ((abs(x - lastx) < 5 and event.key != "y") or
3040-
(abs(y - lasty) < 5 and event.key != "x")):
3024+
if ((abs(x - start_x) < 5 and event.key != "y") or
3025+
(abs(y - start_y) < 5 and event.key != "x")):
30413026
self._xypress = None
30423027
self.release(event)
30433028
self.draw()
30443029
return
30453030

3046-
# detect twinx, twiny axes and avoid double zooming
3047-
twinx, twiny = False, False
3048-
if last_a:
3049-
for la in last_a:
3050-
if a.get_shared_x_axes().joined(a, la):
3051-
twinx = True
3052-
if a.get_shared_y_axes().joined(a, la):
3053-
twiny = True
3054-
last_a.append(a)
3055-
3056-
if self._button_pressed == 1:
3057-
direction = 'in'
3058-
elif self._button_pressed == 3:
3059-
direction = 'out'
3060< B33F span class="diff-text-marker">-
else:
3061-
continue
3031+
# Detect whether this axes is twinned with an earlier axes in the
3032+
# list of zoomed axes, to avoid double zooming.
3033+
twinx = any(ax.get_shared_x_axes().joined(ax, prev)
3034+
for prev in self._zoom_info["axes"][:i])
3035+
twiny = any(ax.get_shared_y_axes().joined(ax, prev)
3036+
for prev in self._zoom_info["axes"][:i])
30623037

3063-
a._set_view_from_bbox((lastx, lasty, x, y), direction,
3064-
event.key, twinx, twiny)
3038+
ax._set_view_from_bbox(
3039+
(start_x, start_y, x, y), self._zoom_info["direction"],
3040+
event.key, twinx, twiny)
30653041

30663042
self.draw()
3067-
self._xypress = None
3068-
self._button_pressed = None
3043+
self._zoom_info = None
30693044

30703045
self.push_current()
30713046
self.release(event)

0 commit comments

Comments
 (0)
0