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 57546ca

Browse filesBrowse files
dopplershiftMeeseeksDev[bot]
authored and
MeeseeksDev[bot]
committed
Backport PR #9359: Keep track of axes in interactive navigation.
1 parent 0ced8c1 commit 57546ca
Copy full SHA for 57546ca

File tree

Expand file treeCollapse file tree

2 files changed

+31
-39
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+31
-39
lines changed

‎lib/matplotlib/backend_bases.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_bases.py
+29-37Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import sys
4747
import time
4848
import warnings
49+
from weakref import WeakKeyDictionary
4950

5051
import numpy as np
5152
import matplotlib.cbook as cbook
@@ -2781,9 +2782,7 @@ class NavigationToolbar2(object):
27812782
def __init__(self, canvas):
27822783
self.canvas = canvas
27832784
canvas.toolbar = self
2784-
# a dict from axes index to a list of view limits
2785-
self._views = cbook.Stack()
2786-
self._positions = cbook.Stack() # stack of subplot positions
2785+
self._nav_stack = cbook.Stack()
27872786
self._xypress = None # the location and axis info at the time
27882787
# of the press
27892788
self._idPress = None
@@ -2805,19 +2804,20 @@ def __init__(self, canvas):
28052804
self.set_history_buttons()
28062805

28072806
@partial(canvas.mpl_connect, 'draw_event')
2808-
def define_home(event):
2809-
self.push_current()
2810-
# The decorator sets `define_home` to the callback cid, so we can
2811-
# disconnect it after the first use.
2812-
canvas.mpl_disconnect(define_home)
2807+
def update_stack(event):
2808+
nav_info = self._nav_stack()
2809+
if (nav_info is None # True initial navigation info.
2810+
# An axes has been added or removed, so update the
2811+
# navigation info too.
2812+
or set(nav_info) != set(self.canvas.figure.axes)):
2813+
self.push_current()
28132814

28142815
def set_message(self, s):
28152816
"""Display a message on toolbar or in status bar."""
28162817

28172818
def back(self, *args):
28182819
"""move back up the view lim stack"""
2819-
self._views.back()
2820-
self._positions.back()
2820+
self._nav_stack.back()
28212821
self.set_history_buttons()
28222822
self._update_view()
28232823

@@ -2836,15 +2836,13 @@ def remove_rubberband(self):
28362836

28372837
def forward(self, *args):
28382838
"""Move forward in the view lim stack."""
2839-
self._views.forward()
2840-
self._positions.forward()
2839+
self._nav_stack.forward()
28412840
self.set_history_buttons()
28422841
self._update_view()
28432842

28442843
def home(self, *args):
28452844
"""Restore the original view."""
2846-
self._views.home()
2847-
self._positions.home()
2845+
self._nav_stack.home()
28482846
self.set_history_buttons()
28492847
self._update_view()
28502848

@@ -3021,16 +3019,13 @@ def _switch_off_zoom_mode(self, event):
30213019

30223020
def push_current(self):
30233021
"""Push the current view limits and position onto the stack."""
3024-
views = []
3025-
pos = []
3026-
for a in self.canvas.figure.get_axes():
3027-
views.append(a._get_view())
3028-
# Store both the original and modified positions
3029-
pos.append((
3030-
a.get_position(True).frozen(),
3031-
a.get_position().frozen()))
3032-
self._views.push(views)
3033-
self._positions.push(pos)
3022+
self._nav_stack.push(
3023+
WeakKeyDictionary(
3024+
{ax: (ax._get_view(),
3025+
# Store both the original and modified positions.
3026+
(ax.get_position(True).frozen(),
3027+
ax.get_position().frozen()))
3028+
for ax in self.canvas.figure.axes}))
30343029
self.set_history_buttons()
30353030

30363031
def release(self, event):
@@ -3151,19 +3146,17 @@ def _update_view(self):
31513146
"""Update the viewlim and position from the view and
31523147
position stack for each axes.
31533148
"""
3154-
3155-
views = self._views()
3156-
if views is None:
3157-
return
3158-
pos = self._positions()
3159-
if pos is None:
3149+
nav_info = self._nav_stack()
3150+
if nav_info is None:
31603151
return
3161-
for i, a in enumerate(self.canvas.figure.get_axes()):
3162-
a._set_view(views[i])
3152+
# Retrieve all items at once to avoid any risk of GC deleting an Axes
3153+
# while in the middle of the loop below.
3154+
items = list(nav_info.items())
3155+
for ax, (view, (pos_orig, pos_active)) in items:
3156+
ax._set_view(view)
31633157
# Restore both the original and modified positions
3164-
a.set_position(pos[i][0], 'original')
3165-
a.set_position(pos[i][1], 'active')
3166-
3158+
ax.set_position(pos_orig, 'original')
3159+
ax.set_position(pos_active, 'active')
31673160
self.canvas.draw_idle()
31683161

31693162
def save_figure(self, *args):
@@ -3181,8 +3174,7 @@ def set_cursor(self, cursor):
31813174

31823175
def update(self):
31833176
"""Reset the axes stack."""
3184-
self._views.clear()
3185-
self._positions.clear()
3177+
self._nav_stack.clear()
31863178
self.set_history_buttons()
31873179

31883180
def zoom(self, *args):

‎lib/matplotlib/backends/backend_wx.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_wx.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,8 +1703,8 @@ def set_message(self, s):
17031703
self.statbar.set_function(s)
17041704

17051705
def set_history_buttons(self):
1706-
can_backward = (self._views._pos > 0)
1707-
can_forward = (self._views._pos < len(self._views._elements) - 1)
1706+
can_backward = self._nav_stack._pos > 0
1707+
can_forward = self._nav_stack._pos < len(self._nav_stack._elements) - 1
17081708
self.EnableTool(self.wx_ids['Back'], can_backward)
17091709
self.EnableTool(self.wx_ids['Forward'], can_forward)
17101710

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.