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 1ce2369

Browse filesBrowse files
authored
Merge pull request #9632 from matplotlib/auto-backport-of-pr-9359
Backport PR #9359 on branch v2.1.x
2 parents 36dafbb + 57546ca commit 1ce2369
Copy full SHA for 1ce2369

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
@@ -2778,9 +2779,7 @@ class NavigationToolbar2(object):
27782779
def __init__(self, canvas):
27792780
self.canvas = canvas
27802781
canvas.toolbar = self
2781-
# a dict from axes index to a list of view limits
2782-
self._views = cbook.Stack()
2783-
self._positions = cbook.Stack() # stack of subplot positions
2782+
self._nav_stack = cbook.Stack()
27842783
self._xypress = None # the location and axis info at the time
27852784
# of the press
27862785
self._idPress = None
@@ -2802,19 +2801,20 @@ def __init__(self, canvas):
28022801
self.set_history_buttons()
28032802

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

28112812
def set_message(self, s):
28122813
"""Display a message on toolbar or in status bar."""
28132814

28142815
def back(self, *args):
28152816
"""move back up the view lim stack"""
2816-
self._views.back()
2817-
self._positions.back()
2817+
self._nav_stack.back()
28182818
self.set_history_buttons()
28192819
self._update_view()
28202820

@@ -2833,15 +2833,13 @@ def remove_rubberband(self):
28332833

28342834
def forward(self, *args):
28352835
"""Move forward in the view lim stack."""
2836-
self._views.forward()
2837-
self._positions.forward()
2836+
self._nav_stack.forward()
28382837
self.set_history_buttons()
28392838
self._update_view()
28402839

28412840
def home(self, *args):
28422841
"""Restore the original view."""
2843-
self._views.home()
2844-
self._positions.home()
2842+
self._nav_stack.home()
28452843
self.set_history_buttons()
28462844
self._update_view()
28472845

@@ -3018,16 +3016,13 @@ def _switch_off_zoom_mode(self, event):
30183016

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

30333028
def release(self, event):
@@ -3148,19 +3143,17 @@ def _update_view(self):
31483143
"""Update the viewlim and position from the view and
31493144
position stack for each axes.
31503145
"""
3151-
3152-
views = self._views()
3153-
if views is None:
3154-
return
3155-
pos = self._positions()
3156-
if pos is None:
3146+
nav_info = self._nav_stack()
3147+
if nav_info is None:
31573148
return
3158-
for i, a in enumerate(self.canvas.figure.get_axes()):
3159-
a._set_view(views[i])
3149+
# Retrieve all items at once to avoid any risk of GC deleting an Axes
3150+
# while in the middle of the loop below.
3151+
items = list(nav_info.items())
3152+
for ax, (view, (pos_orig, pos_active)) in items:
3153+
ax._set_view(view)
31603154
# Restore both the original and modified positions
3161-
a.set_position(pos[i][0], 'original')
3162-
a.set_position(pos[i][1], 'active')
3163-
3155+
ax.set_position(pos_orig, 'original')
3156+
ax.set_position(pos_active, 'active')
31643157
self.canvas.draw_idle()
31653158

31663159
def save_figure(self, *args):
@@ -3178,8 +3171,7 @@ def set_cursor(self, cursor):
31783171

31793172
def update(self):
31803173
"""Reset the axes stack."""
3181-
self._views.clear()
3182-
self._positions.clear()
3174+
self._nav_stack.clear()
31833175
self.set_history_buttons()
31843176

31853177
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.