Skip to content

Work towards removing reuse-of-axes-on-collision. #10660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions lib/matplotlib/cbook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1168,72 +1168,75 @@ def __setitem__(self, k, v):

class Stack(object):
"""
Implement a stack where elements can be pushed on and you can move
back and forth. But no pop. Should mimic home / back / forward
in a browser
Stack of elements with a movable cursor.

Mimics home/back/forward in a web browser.
"""

def __init__(self, default=None):
self.clear()
self._default = default

def __call__(self):
"""return the current element, or None"""
"""Return the current element, or None."""
if not len(self._elements):
return self._default
else:
return self._elements[self._pos]

def __len__(self):
return self._elements.__len__()
return len(self._elements)

def __getitem__(self, ind):
return self._elements.__getitem__(ind)
return self._elements[ind]

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

def back(self):
"""move the position back and return the current element"""
"""Move the position back and return the current element."""
if self._pos > 0:
self._pos -= 1
return self()

def push(self, o):
"""
push object onto stack at current position - all elements
occurring later than the current position are discarded
Push *o* to the stack at current position. Discard all later elements.

*o* is returned.
"""
self._elements = self._elements[:self._pos + 1]
self._elements.append(o)
self._elements = self._elements[:self._pos + 1] + [o]
self._pos = len(self._elements) - 1
return self()

def home(self):
"""push the first element onto the top of the stack"""
"""
Push the first element onto the top of the stack.

The first element is returned.
"""
if not len(self._elements):
return
self.push(self._elements[0])
return self()

def empty(self):
"""Return whether the stack is empty."""
return len(self._elements) == 0

def clear(self):
"""empty the stack"""
"""Empty the stack."""
self._pos = -1
self._elements = []

def bubble(self, o):
"""
raise *o* to the top of the stack and return *o*. *o* must be
in the stack
"""
Raise *o* to the top of the stack. *o* must be present in the stack.

*o* is returned.
"""
if o not in self._elements:
raise ValueError('Unknown element o')
old = self._elements[:]
Expand All @@ -1249,7 +1252,7 @@ def bubble(self, o):
return o

def remove(self, o):
'remove element *o* from the stack'
"""Remove *o* from the stack."""
if o not in self._elements:
raise ValueError('Unknown element o')
old = self._elements[:]
Expand Down
14 changes: 10 additions & 4 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1792,11 +1792,8 @@ def gca(self, **kwargs):
# if the user has specified particular projection detail
# then build up a key which can represent this
else:
# we don't want to modify the original kwargs
# so take a copy so that we can do what we like to it
kwargs_copy = kwargs.copy()
projection_class, _, key = process_projection_requirements(
self, **kwargs_copy)
self, **kwargs)

# let the returned axes have any gridspec by removing it from
# the key
Expand All @@ -1806,6 +1803,15 @@ def gca(self, **kwargs):
# if the cax matches this key then return the axes, otherwise
# continue and a new axes will be created
if key == ckey and isinstance(cax, projection_class):
cbook.warn_deprecated(
"3.0",
"Calling `gca()` using the same arguments as a "
"previous axes currently reuses the earlier "
"instance. In a future version, a new instance will "
"always be created and returned. Meanwhile, this "
"warning can be suppressed, and the future behavior "
"ensured, by passing a unique label to each axes "
"instance.")
return cax
else:
warnings.warn('Requested projection is different from '
Expand Down
10 changes: 3 additions & 7 deletions lib/matplotlib/projections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,11 @@ def get_projection_class(projection=None):

def process_projection_requirements(figure, *args, **kwargs):
"""
Handle the args/kwargs to for add_axes/add_subplot/gca,
returning::
Handle the args/kwargs to add_axes/add_subplot/gca, returning::

(axes_proj_class, proj_class_kwargs, proj_stack_key)

Which can be used for new axes initialization/identification.

.. note:: **kwargs** is modified in place.

which can be used for new axes initialization/identification.
"""
ispolar = kwargs.pop('polar', False)
projection = kwargs.pop('projection', None)
Expand All @@ -94,7 +90,7 @@ def process_projection_requirements(figure, *args, **kwargs):
kwargs.update(**extra_kwargs)
else:
raise TypeError('projection must be a string, None or implement a '
'_as_mpl_axes method. Got %r' % projection)
'_as_mpl_axes method. Got %r' % projection)

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