Skip to content

Commit a2f01cb

Browse files
committed
Simplify interactive zoom handling.
- During interactive zoom, one can additionally press x or y to restrict zooming to the x or y direction. Instead of adding separate key_press_handlers to check that and maintaining that state in `_zoom_mode`, one can simply read `event.key` in the mouse handler (because the key needs to stay pressed for this to be active -- there's no behavior change). - The `ids_zoom` list of callback ids can then be replaced by a single `_id_zoom`. - When stashing info in `_xypress` to perform the zoom, one only needs to know where the zoom started (x, y) and the underlying axes (a). The index (i) and view (a._get_view()) are unused, so just remove them.
1 parent 2789820 commit a2f01cb

File tree

1 file changed

+18
-38
lines changed

1 file changed

+18
-38
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,9 +2687,7 @@ def __init__(self, canvas):
26872687
self._init_toolbar()
26882688
self._idDrag = self.canvas.mpl_connect(
26892689
'motion_notify_event', self.mouse_move)
2690-
2691-
self._ids_zoom = []
2692-
self._zoom_mode = None
2690+
self._id_zoom = None
26932691

26942692
self._button_pressed = None # determined by button pressed at start
26952693

@@ -2901,14 +2899,13 @@ def press_zoom(self, event):
29012899
"""Callback for mouse button press in zoom to rect mode."""
29022900
# If we're already in the middle of a zoom, pressing another
29032901
# button works to "cancel"
2904-
if self._ids_zoom:
2905-
for zoom_id in self._ids_zoom:
2906-
self.canvas.mpl_disconnect(zoom_id)
2902+
if self._id_zoom is not None:
2903+
self.canvas.mpl_disconnect(self._id_zoom)
29072904
self.release(event)
29082905
self.draw()
29092906
self._xypress = None
29102907
self._button_pressed = None
2911-
self._ids_zoom = []
2908+
self._id_zoom = None
29122909
return
29132910

29142911
if event.button in [1, 3]:
@@ -2923,30 +2920,16 @@ def press_zoom(self, event):
29232920

29242921
x, y = event.x, event.y
29252922
self._xypress = []
2926-
for i, a in enumerate(self.canvas.figure.get_axes()):
2923+
for a in self.canvas.figure.get_axes():
29272924
if (x is not None and y is not None and a.in_axes(event) and
29282925
a.get_navigate() and a.can_zoom()):
2929-
self._xypress.append((x, y, a, i, a._get_view()))
2930-
2931-
id1 = self.canvas.mpl_connect('motion_notify_event', self.drag_zoom)
2932-
id2 = self.canvas.mpl_connect('key_press_event',
2933-
self._switch_on_zoom_mode)
2934-
id3 = self.canvas.mpl_connect('key_release_event',
2935-
self._switch_off_zoom_mode)
2926+
self._xypress.append((x, y, a))
29362927

2937-
self._ids_zoom = id1, id2, id3
2938-
self._zoom_mode = event.key
2928+
self._id_zoom = self.canvas.mpl_connect(
2929+
'motion_notify_event', self.drag_zoom)
29392930

29402931
self.press(event)
29412932

2942-
def _switch_on_zoom_mode(self, event):
2943-
self._zoom_mode = event.key
2944-
self.mouse_move(event)
2945-
2946-
def _switch_off_zoom_mode(self, event):
2947-
self._zoom_mode = None
2948-
self.mouse_move(event)
2949-
29502933
def push_current(self):
29512934
"""Push the current view limits and position onto the stack."""
29522935
self._nav_stack.push(
@@ -2991,20 +2974,20 @@ def drag_zoom(self, event):
29912974
"""Callback for dragging in zoom mode."""
29922975
if self._xypress:
29932976
x, y = event.x, event.y
2994-
lastx, lasty, a, ind, view = self._xypress[0]
2977+
lastx, lasty, a = self._xypress[0]
29952978
(x1, y1), (x2, y2) = np.clip(
29962979
[[lastx, lasty], [x, y]], a.bbox.min, a.bbox.max)
2997-
if self._zoom_mode == "x":
2980+
if event.key == "x":
29982981
y1, y2 = a.bbox.intervaly
2999-
elif self._zoom_mode == "y":
2982+
elif event.key == "y":
30002983
x1, x2 = a.bbox.intervalx
30012984
self.draw_rubberband(event, x1, y1, x2, y2)
30022985

30032986
def release_zoom(self, event):
30042987
"""Callback for mouse button release in zoom to rect mode."""
3005-
for zoom_id in self._ids_zoom:
3006-
self.canvas.mpl_disconnect(zoom_id)
3007-
self._ids_zoom = []
2988+
if self._id_zoom is not None:
2989+
self.canvas.mpl_disconnect(self._id_zoom)
2990+
self._id_zoom = None
30082991

30092992
self.remove_rubberband()
30102993

@@ -3013,14 +2996,13 @@ def release_zoom(self, event):
30132996

30142997
last_a = []
30152998

3016-
for cur_xypress in self._xypress:
2999+
for lastx, lasty, a in self._xypress:
30173000
x, y = event.x, event.y
3018-
lastx, lasty, a, ind, view = cur_xypress
30193001
# ignore singular clicks - 5 pixels is a threshold
30203002
# allows the user to "cancel" a zoom action
30213003
# by zooming by less than 5 pixels
3022-
if ((abs(x - lastx) < 5 and self._zoom_mode != "y") or
3023-
(abs(y - lasty) < 5 and self._zoom_mode != "x")):
3004+
if ((abs(x - lastx) < 5 and event.key != "y") or
3005+
(abs(y - lasty) < 5 and event.key != "x")):
30243006
self._xypress = None
30253007
self.release(event)
30263008
self.draw()
@@ -3044,14 +3026,12 @@ def release_zoom(self, event):
30443026
continue
30453027

30463028
a._set_view_from_bbox((lastx, lasty, x, y), direction,
3047-
self._zoom_mode, twinx, twiny)
3029+
event.key, twinx, twiny)
30483030

30493031
self.draw()
30503032
self._xypress = None
30513033
self._button_pressed = None
30523034

3053-
self._zoom_mode = None
3054-
30553035
self.push_current()
30563036
self.release(event)
30573037

0 commit comments

Comments
 (0)