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

Commitf21c036

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 parentfa95b58 commitf21c036

File tree

2 files changed

+67
-47
lines changed

2 files changed

+67
-47
lines changed

‎lib/matplotlib/figure.py

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class AxesStack(Stack):
7272
7373
"""
7474
def__init__(self):
75+
cbook.warn_deprecated("2.0")
7576
Stack.__init__(self)
7677
self._ind=0
7778

@@ -156,6 +157,62 @@ def __contains__(self, a):
156157
returnainself.as_list()
157158

158159

160+
class_AxesStack(object):
161+
"""Lightweight stack that tracks Axes in a Figure.
162+
"""
163+
164+
def__init__(self):
165+
# We maintain a list of (creation_index, key, axes) tuples.
166+
# We do not use an OrderedDict because 1. the keys may not be hashable
167+
# and 2. we need to directly find a pair corresponding to an axes (i.e.
168+
# we'd really need a two-way dict).
169+
self._items= []
170+
self._created=0
171+
172+
defas_list(self):
173+
"""Copy of the list of axes, in the order of insertion.
174+
"""
175+
return [axfor_,_,axinsorted(self._items)]
176+
177+
defget(self,key):
178+
"""Find the axes corresponding to a key; defaults to `None`.
179+
"""
180+
returnnext((axfor_,k,axinself._itemsifk==key),None)
181+
182+
defcurrent_key_axes(self):
183+
"""Return the topmost `(key, axes)` pair, or `(None, None)` if empty.
184+
"""
185+
_,key,ax= (self._itemsor [(None,None,None)])[-1]
186+
returnkey,ax
187+
188+
defadd(self,key,ax):
189+
"""Append a `(key, axes)` pair, unless the axes are already present.
190+
"""
191+
# Skipping existing Axes is needed to support calling `add_axes` with
192+
# an already existing Axes.
193+
ifnotany(a==axfor_,_,ainself._items):
194+
self._items.append((self._created,key,ax))
195+
self._created+=1
196+
197+
defbubble(self,ax):
198+
"""Move an axes and its corresponding key to the top.
199+
"""
200+
idx,= (idxforidx, (_,_,a)inenumerate(self._items)ifa==ax)
201+
self._items.append(self._items[idx])
202+
delself._items[idx]
203+
204+
defremove(self,ax):
205+
"""Remove an axes and its corresponding key.
206+
"""
207+
idx,= (idxforidx, (_,_,a)inenumerate(self._items)ifa==ax)
208+
delself._items[idx]
209+
210+
defclear(self):
211+
"""Clear the stack.
212+
"""
213+
delself._items[:]
214+
215+
159216
classSubplotParams(object):
160217
"""
161218
A class to hold the parameters for a subplot
@@ -354,7 +411,7 @@ def __init__(self,
354411
self.subplotpars=subplotpars
355412
self.set_tight_layout(tight_layout)
356413

357-
self._axstack=AxesStack()# track all figure axes and current axes
414+
self._axstack=_AxesStack()# track all figure axes and current axes
358415
self.clf()
359416
self._cachedRenderer=None
360417

@@ -402,10 +459,8 @@ def show(self, warn=True):
402459
"matplotlib is currently using a non-GUI backend, "
403460
"so cannot show the figure")
404461

405-
def_get_axes(self):
406-
returnself._axstack.as_list()
407-
408-
axes=property(fget=_get_axes,doc="Read-only: list of axes in Figure")
462+
axes=property(lambdaself:self._axstack.as_list(),
463+
doc="Read-only: list of axes in Figure")
409464

410465
def_get_dpi(self):
411466
returnself._dpi
@@ -817,36 +872,6 @@ def delaxes(self, a):
817872
func(self)
818873
self.stale=True
819874

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

901926
# shortcut the projection "key" modifications later on, if an axes
902927
# with the exact args/kwargs exists, return it immediately.
903-
key=self._make_key(*args,**kwargs)
928+
key=(args,kwargs)
904929
ax=self._axstack.get(key)
905-
ifaxisnotNone:
930+
ifax:
906931
self.sca(ax)
907932
returnax
908933

@@ -919,7 +944,7 @@ def add_axes(self, *args, **kwargs):
919944
# check that an axes of this type doesn't already exist, if it
920945
# does, set it as active and return it
921946
ax=self._axstack.get(key)
922-
ifaxisnotNoneandisinstance(ax,projection_class):
947+
ifisinstance(ax,projection_class):
923948
self.sca(ax)
924949
returnax
925950

@@ -993,15 +1018,14 @@ def add_subplot(self, *args, **kwargs):
9931018
raiseValueError(msg)
9941019
# make a key for the subplot (which includes the axes object id
9951020
# in the hash)
996-
key=self._make_key(*args,**kwargs)
1021+
key=(args,kwargs)
9971022
else:
9981023
projection_class,kwargs,key=process_projection_requirements(
9991024
self,*args,**kwargs)
10001025

10011026
# try to find the axes with this key in the stack
10021027
ax=self._axstack.get(key)
1003-
1004-
ifaxisnotNone:
1028+
ifax:
10051029
ifisinstance(ax,projection_class):
10061030
# the axes already existed, so set it as active & return
10071031
self.sca(ax)
@@ -1483,7 +1507,7 @@ def _gci(self):
14831507
do not use elsewhere.
14841508
"""
14851509
# Look first for an image in the current Axes:
1486-
cax=self._axstack.current_key_axes()[1]
1510+
ckey,cax=self._axstack.current_key_axes()
14871511
ifcaxisNone:
14881512
returnNone
14891513
im=cax._gci()

‎lib/matplotlib/projections/__init__.py

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

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

110106

111107
defget_projection_names():

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp