Skip to content

Commit fbce132

Browse files
committed
Work towards removing reuse-of-axes-on-collision.
Currently, Matplotlib reuses axes when add_axes() is called a second time with the same arguments. This behavior is deprecated since 2.1. However we forgot to deprecate the same behavior in gca(), so we can't remove that behavior yet. Also cleanup docstrings of Stack class. Also, process_projection_requirements cannot modify the outer kwargs (because `**kwargs` is always a copy), so remove the incorrect note regarding the need for copies.
1 parent e54939a commit fbce132

File tree

3 files changed

+28
-33
lines changed

3 files changed

+28
-33
lines changed

lib/matplotlib/cbook/__init__.py

+16-23
Original file line numberDiff line numberDiff line change
@@ -1168,72 +1168,65 @@ def __setitem__(self, k, v):
11681168

11691169
class Stack(object):
11701170
"""
1171-
Implement a stack where elements can be pushed on and you can move
1172-
back and forth. But no pop. Should mimic home / back / forward
1173-
in a browser
1171+
Stack of elements with a movable cursor.
1172+
1173+
Mimics home/back/forward in a web browser.
11741174
"""
11751175

11761176
def __init__(self, default=None):
11771177
self.clear()
11781178
self._default = default
11791179

11801180
def __call__(self):
1181-
"""return the current element, or None"""
1181+
"""Return the current element, or None."""
11821182
if not len(self._elements):
11831183
return self._default
11841184
else:
11851185
return self._elements[self._pos]
11861186

11871187
def __len__(self):
1188-
return self._elements.__len__()
1188+
return len(self._elements)
11891189

11901190
def __getitem__(self, ind):
1191-
return self._elements.__getitem__(ind)
1191+
return self._elements[ind]
11921192

11931193
def forward(self):
1194-
"""move the position forward and return the current element"""
1195-
n = len(self._elements)
1196-
if self._pos < n - 1:
1197-
self._pos += 1
1194+
"""Move the position forward and return the current element."""
1195+
self._pos = min(self._pos + 1, len(self._elements) - 1)
11981196
return self()
11991197

12001198
def back(self):
1201-
"""move the position back and return the current element"""
1199+
"""Move the position back and return the current element."""
12021200
if self._pos > 0:
12031201
self._pos -= 1
12041202
return self()
12051203

12061204
def push(self, o):
12071205
"""
1208-
push object onto stack at current position - all elements
1209-
occurring later than the current position are discarded
1206+
Push element to stack at current position, discard all later elements.
12101207
"""
1211-
self._elements = self._elements[:self._pos + 1]
1212-
self._elements.append(o)
1208+
self._elements = self._elements[:self._pos + 1] + [o]
12131209
self._pos = len(self._elements) - 1
12141210
return self()
12151211

12161212
def home(self):
1217-
"""push the first element onto the top of the stack"""
1213+
"""Push the first element onto the top of the stack."""
12181214
if not len(self._elements):
12191215
return
12201216
self.push(self._elements[0])
12211217
return self()
12221218

12231219
def empty(self):
1220+
"""Return whether the stack is empty."""
12241221
return len(self._elements) == 0
12251222

12261223
def clear(self):
1227-
"""empty the stack"""
1224+
"""Empty the stack."""
12281225
self._pos = -1
12291226
self._elements = []
12301227

12311228
def bubble(self, o):
1232-
"""
1233-
raise *o* to the top of the stack and return *o*. *o* must be
1234-
in the stack
1235-
"""
1236-
1229+
"""Raise element (present in the stack) to the stack top; return it."""
12371230
if o not in self._elements:
12381231
raise ValueError('Unknown element o')
12391232
old = self._elements[:]
@@ -1249,7 +1242,7 @@ def bubble(self, o):
12491242
return o
12501243

12511244
def remove(self, o):
1252-
'remove element *o* from the stack'
1245+
"""Remove element from the stack."""
12531246
if o not in self._elements:
12541247
raise ValueError('Unknown element o')
12551248
old = self._elements[:]

lib/matplotlib/figure.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -1792,11 +1792,8 @@ def gca(self, **kwargs):
17921792
# if the user has specified particular projection detail
17931793
# then build up a key which can represent this
17941794
else:
1795-
# we don't want to modify the original kwargs
1796-
# so take a copy so that we can do what we like to it
1797-
kwargs_copy = kwargs.copy()
17981795
projection_class, _, key = process_projection_requirements(
1799-
self, **kwargs_copy)
1796+
self, **kwargs)
18001797

18011798
# let the returned axes have any gridspec by removing it from
18021799
# the key
@@ -1806,6 +1803,15 @@ def gca(self, **kwargs):
18061803
# if the cax matches this key then return the axes, otherwise
18071804
# continue and a new axes will be created
18081805
if key == ckey and isinstance(cax, projection_class):
1806+
cbook.warn_deprecated(
1807+
"3.0",
1808+
"Calling `gca()` using the same arguments as a "
1809+
"previous axes currently reuses the earlier "
1810+
"instance. In a future version, a new instance will "
1811+
"always be created and returned. Meanwhile, this "
1812+
"warning can be suppressed, and the future behavior "
1813+
"ensured, by passing a unique label to each axes "
1814+
"instance.")
18091815
return cax
18101816
else:
18111817
warnings.warn('Requested projection is different from '

lib/matplotlib/projections/__init__.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,11 @@ def get_projection_class(projection=None):
6767

6868
def process_projection_requirements(figure, *args, **kwargs):
6969
"""
70-
Handle the args/kwargs to for add_axes/add_subplot/gca,
71-
returning::
70+
Handle the args/kwargs to for add_axes/add_subplot/gca, returning::
7271
7372
(axes_proj_class, proj_class_kwargs, proj_stack_key)
7473
7574
Which can be used for new axes initialization/identification.
76-
77-
.. note:: **kwargs** is modified in place.
78-
7975
"""
8076
ispolar = kwargs.pop('polar', False)
8177
projection = kwargs.pop('projection', None)
@@ -94,7 +90,7 @@ def process_projection_requirements(figure, *args, **kwargs):
9490
kwargs.update(**extra_kwargs)
9591
else:
9692
raise TypeError('projection must be a string, None or implement a '
97-
'_as_mpl_axes method. Got %r' % projection)
93+
'_as_mpl_axes method. Got %r' % projection)
9894

9995
# Make the key without projection kwargs, this is used as a unique
10096
# lookup for axes instances

0 commit comments

Comments
 (0)