Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 30ee515

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 30ee515

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

lib/matplotlib/cbook/__init__.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,72 +1168,75 @@ 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 *o* to the stack at current position. Discard all later elements.
1207+
1208+
*o* is returned.
12101209
"""
1211-
self._elements = self._elements[:self._pos + 1]
1212-
self._elements.append(o)
1210+
self._elements = self._elements[:self._pos + 1] + [o]
12131211
self._pos = len(self._elements) - 1
12141212
return self()
12151213

12161214
def home(self):
1217-
"""push the first element onto the top of the stack"""
1215+
"""
1216+
Push the first element onto the top of the stack.
1217+
1218+
The first element is returned.
1219+
"""
12181220
if not len(self._elements):
12191221
return
12201222
self.push(self._elements[0])
12211223
return self()
12221224

12231225
def empty(self):
1226+
"""Return whether the stack is empty."""
12241227
return len(self._elements) == 0
12251228

12261229
def clear(self):
1227-
"""empty the stack"""
1230+
"""Empty the stack."""
12281231
self._pos = -1
12291232
self._elements = []
12301233

12311234
def bubble(self, o):
12321235
"""
1233-
raise *o* to the top of the stack and return *o*. *o* must be
1234-
in the stack
1235-
"""
1236+
Raise *o* to the top of the stack. *o* must be present in the stack.
12361237
1238+
*o* is returned.
1239+
"""
12371240
if o not in self._elements:
12381241
raise ValueError('Unknown element o')
12391242
old = self._elements[:]
@@ -1249,7 +1252,7 @@ def bubble(self, o):
12491252
return o
12501253

12511254
def remove(self, o):
1252-
'remove element *o* from the stack'
1255+
"""Remove *o* from the stack."""
12531256
if o not in self._elements:
12541257
raise ValueError('Unknown element o')
12551258
old = self._elements[:]

lib/matplotlib/figure.py

Lines changed: 10 additions & 4 deletions
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

Lines changed: 3 additions & 7 deletions
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 add_axes/add_subplot/gca, returning::
7271
7372
(axes_proj_class, proj_class_kwargs, proj_stack_key)
7473
75-
Which can be used for new axes initialization/identification.
76-
77-
.. note:: **kwargs** is modified in place.
78-
74+
which can be used for new axes initialization/identification.
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)