Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit7eb590d

Browse files
committed
Switch to a private, simpler AxesStack.
The current implementation of AxesStack subclasses cbook.Stack, whichrequires hashable keys, which leads to additional complexity on thecaller's side (`_make_key`).Instead, switch to using two lists (keys and axes) and relying on`list.index`, which makes the implementation much simpler.Also make the new class private and deprecate the previous one.
1 parent00ae164 commit7eb590d

File tree

2 files changed

+74
-48
lines changed

2 files changed

+74
-48
lines changed

‎lib/matplotlib/figure.py

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
importsix
1818

19-
importwarnings
2019
fromoperatorimportitemgetter
20+
importwarnings
2121

2222
importnumpyasnp
2323

@@ -73,6 +73,7 @@ class AxesStack(Stack):
7373
7474
"""
7575
def__init__(self):
76+
cbook.warn_deprecated("2.0")
7677
Stack.__init__(self)
7778
self._ind=0
7879

@@ -157,6 +158,68 @@ def __contains__(self, a):
157158
returnainself.as_list()
158159

159160

161+
class_AxesStack(object):
162+
"""Lightweight stack that tracks Axes in a Figure.
163+
"""
164+
165+
# We do not subclass the Stack class from cbook to avoid hashability
166+
# issues.
167+
168+
def__init__(self):
169+
self._keys= []
170+
self._axes= []
171+
self._axes_ordered= []
172+
173+
defas_list(self):
174+
"""Copy of the list of axes, in the order of insertion.
175+
"""
176+
returnself._axes_ordered[:]
177+
178+
defget(self,key):
179+
"""Find the axes corresponding to a key; defaults to `None`.
180+
"""
181+
try:
182+
returnself._axes[self._keys.index(key)]
183+
exceptValueError:
184+
returnNone
185+
186+
defcurrent_key_axes(self):
187+
"""Return the topmost key, axes pair, or `None, None` if empty.
188+
"""
189+
return (self._keys[-1],self._axes[-1])ifself._keyselse (None,None)
190+
191+
defadd(self,key,ax):
192+
"""Append a key, axes pair, unless the axes are already present.
193+
"""
194+
# Skipping existing Axes is needed to support calling `add_axes` with
195+
# an already existing Axes.
196+
ifaxinself._axes_ordered:
197+
return
198+
self._keys.append(key)
199+
self._axes.append(ax)
200+
self._axes_ordered.append(ax)
201+
202+
defbubble(self,ax):
203+
"""Move an axes and its corresponding key to the top.
204+
"""
205+
idx=self._axes.index(ax)
206+
self._keys.append(self._keys[idx])
207+
self._axes.append(self._axes[idx])
208+
delself._keys[idx],self._axes[idx]
209+
210+
defremove(self,ax):
211+
"""Remove an axes and its corresponding key.
212+
"""
213+
delself._keys[self._axes.index(ax)]
214+
self._axes.remove(ax)
215+
self._axes_ordered.remove(ax)
216+
217+
defclear(self):
218+
"""Clear the stack.
219+
"""
220+
delself._keys[:],self._axes[:],self._axes_ordered[:]
221+
222+
160223
classSubplotParams(object):
161224
"""
162225
A class to hold the parameters for a subplot
@@ -350,7 +413,7 @@ def __init__(self,
350413
self.subplotpars=subplotpars
351414
self.set_tight_layout(tight_layout)
352415

353-
self._axstack=AxesStack()# track all figure axes and current axes
416+
self._axstack=_AxesStack()# track all figure axes and current axes
354417
self.clf()
355418
self._cachedRenderer=None
356419

@@ -398,10 +461,8 @@ def show(self, warn=True):
398461
"matplotlib is currently using a non-GUI backend, "
399462
"so cannot show the figure")
400463

401-
def_get_axes(self):
402-
returnself._axstack.as_list()
403-
404-
axes=property(fget=_get_axes,doc="Read-only: list of axes in Figure")
464+
axes=property(lambdaself:self._axstack.as_list(),
465+
doc="Read-only: list of axes in Figure")
405466

406467
def_get_dpi(self):
407468
returnself._dpi
@@ -812,36 +873,6 @@ def delaxes(self, a):
812873
func(self)
813874
self.stale=True
814875

815-
def_make_key(self,*args,**kwargs):
816-
'make a hashable key out of args and kwargs'
817-
818-
deffixitems(items):
819-
#items may have arrays and lists in them, so convert them
820-
# to tuples for the key
821-
ret= []
822-
fork,vinitems:
823-
# some objects can define __getitem__ without being
824-
# iterable and in those cases the conversion to tuples
825-
# will fail. So instead of using the iterable(v) function
826-
# we simply try and convert to a tuple, and proceed if not.
827-
try:
828-
v=tuple(v)
829-
exceptException:
830-
pass
831-
ret.append((k,v))
832-
returntuple(ret)
833-
834-
deffixlist(args):
835-
ret= []
836-
forainargs:
837-
ifiterable(a):
838-
a=tuple(a)
839-
ret.append(a)
840-
returntuple(ret)
841-
842-
key=fixlist(args),fixitems(six.iteritems(kwargs))
843-
returnkey
844-
845876
@docstring.dedent_interpd
846877
defadd_axes(self,*args,**kwargs):
847878
"""
@@ -895,9 +926,9 @@ def add_axes(self, *args, **kwargs):
895926

896927
# shortcut the projection "key" modifications later on, if an axes
897928
# with the exact args/kwargs exists, return it immediately.
898-
key=self._make_key(*args,**kwargs)
929+
key=(args,kwargs)
899930
ax=self._axstack.get(key)
900-
ifaxisnotNone:
931+
ifax:
901932
self.sca(ax)
902933
returnax
903934

@@ -914,7 +945,7 @@ def add_axes(self, *args, **kwargs):
914945
# check that an axes of this type doesn't already exist, if it
915946
# does, set it as active and return it
916947
ax=self._axstack.get(key)
917-
ifaxisnotNoneandisinstance(ax,projection_class):
948+
ifisinstance(ax,projection_class):
918949
self.sca(ax)
919950
returnax
920951

@@ -988,15 +1019,14 @@ def add_subplot(self, *args, **kwargs):
9881019
raiseValueError(msg)
9891020
# make a key for the subplot (which includes the axes object id
9901021
# in the hash)
991-
key=self._make_key(*args,**kwargs)
1022+
key=(args,kwargs)
9921023
else:
9931024
projection_class,kwargs,key=process_projection_requirements(
9941025
self,*args,**kwargs)
9951026

9961027
# try to find the axes with this key in the stack
9971028
ax=self._axstack.get(key)
998-
999-
ifaxisnotNone:
1029+
ifax:
10001030
ifisinstance(ax,projection_class):
10011031
# the axes already existed, so set it as active & return
10021032
self.sca(ax)
@@ -1496,7 +1526,7 @@ def _gci(self):
14961526
do not use elsewhere.
14971527
"""
14981528
# Look first for an image in the current Axes:
1499-
cax=self._axstack.current_key_axes()[1]
1529+
ckey,cax=self._axstack.current_key_axes()
15001530
ifcaxisNone:
15011531
returnNone
15021532
im=cax._gci()

‎lib/matplotlib/projections/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,7 @@ def process_projection_requirements(figure, *args, **kwargs):
103103
raiseTypeError('projection must be a string, None or implement a '
104104
'_as_mpl_axes method. Got %r'%projection)
105105

106-
# Make the key without projection kwargs, this is used as a unique
107-
# lookup for axes instances
108-
key=figure._make_key(*args,**kwargs)
109-
110-
returnprojection_class,kwargs,key
106+
returnprojection_class,kwargs, (args,kwargs)
111107

112108

113109
defget_projection_names():

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp