16
16
17
17
import six
18
18
19
- import warnings
20
19
from operator import itemgetter
20
+ import warnings
21
21
22
22
import numpy as np
23
23
@@ -73,6 +73,7 @@ class AxesStack(Stack):
73
73
74
74
"""
75
75
def __init__ (self ):
76
+ cbook .warn_deprecated ("2.0" )
76
77
Stack .__init__ (self )
77
78
self ._ind = 0
78
79
@@ -157,6 +158,59 @@ def __contains__(self, a):
157
158
return a in self .as_list ()
158
159
159
160
161
+ class _AxesStack :
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
+
172
+ axes = property (lambda self : self ._axes [:],
173
+ doc = "Copy of the list of axes." )
174
+
175
+ def get (self , key ):
176
+ """Find the axes corresponding to a key; defaults to `None`.
177
+ """
178
+ try :
179
+ return self ._axes [self ._keys .index (key )]
180
+ except ValueError :
181
+ return None
182
+
183
+ def current_key_axes (self ):
184
+ """Return the topmost key, axes pair, or `None, None` if empty.
185
+ """
186
+ return (self ._keys [- 1 ], self ._axes [- 1 ]) if self ._keys else (None , None )
187
+
188
+ def add (self , key , ax ):
189
+ """Append a key, axes pair.
190
+ """
191
+ self ._keys .append (key )
192
+ self ._axes .append (ax )
193
+
194
+ def bubble (self , ax ):
195
+ """Move an axes and its corresponding key to the top.
196
+ """
197
+ idx = self ._axes .index (ax )
198
+ self ._keys .append (self ._keys [idx ])
199
+ self ._axes .append (self ._axes [idx ])
200
+ del self ._keys [idx ], self ._axes [idx ]
201
+
202
+ def remove (self , ax ):
203
+ """Remove an axes and its corresponding key.
204
+ """
205
+ idx = self ._axes .index (ax )
206
+ del self ._keys [idx ], self ._axes [idx ]
207
+
208
+ def clear (self ):
209
+ """Clear the stack.
210
+ """
211
+ del self ._keys [:], self ._axes [:] # Py2 doesn't have list.clear.
212
+
213
+
160
214
class SubplotParams (object ):
161
215
"""
162
216
A class to hold the parameters for a subplot
@@ -350,7 +404,7 @@ def __init__(self,
350
404
self .subplotpars = subplotpars
351
405
self .set_tight_layout (tight_layout )
352
406
353
- self ._axstack = AxesStack () # track all figure axes and current axes
407
+ self ._axstack = _AxesStack () # track all figure axes and current axes
354
408
self .clf ()
355
409
self ._cachedRenderer = None
356
410
@@ -399,7 +453,7 @@ def show(self, warn=True):
399
453
"so cannot show the figure" )
400
454
401
455
def _get_axes (self ):
402
- return self ._axstack .as_list ()
456
+ return self ._axstack .axes
403
457
404
458
axes = property (fget = _get_axes , doc = "Read-only: list of axes in Figure" )
405
459
@@ -812,36 +866,6 @@ def delaxes(self, a):
812
866
func (self )
813
867
self .stale = True
814
868
815
- def _make_key (self , * args , ** kwargs ):
816
- 'make a hashable key out of args and kwargs'
817
-
818
- def fixitems (items ):
819
- #items may have arrays and lists in them, so convert them
820
- # to tuples for the key
821
- ret = []
822
- for k , v in items :
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
- except Exception :
830
- pass
831
- ret .append ((k , v ))
832
- return tuple (ret )
833
-
834
- def fixlist (args ):
835
- ret = []
836
- for a in args :
837
- if iterable (a ):
838
- a = tuple (a )
839
- ret .append (a )
840
- return tuple (ret )
841
-
842
- key = fixlist (args ), fixitems (six .iteritems (kwargs ))
843
- return key
844
-
845
869
@docstring .dedent_interpd
846
870
def add_axes (self , * args , ** kwargs ):
847
871
"""
@@ -895,9 +919,9 @@ def add_axes(self, *args, **kwargs):
895
919
896
920
# shortcut the projection "key" modifications later on, if an axes
897
921
# with the exact args/kwargs exists, return it immediately.
898
- key = self . _make_key ( * args , ** kwargs )
922
+ key = ( args , kwargs )
899
923
ax = self ._axstack .get (key )
900
- if ax is not None :
924
+ if ax :
901
925
self .sca (ax )
902
926
return ax
903
927
@@ -914,7 +938,7 @@ def add_axes(self, *args, **kwargs):
914
938
# check that an axes of this type doesn't already exist, if it
915
939
# does, set it as active and return it
916
940
ax = self ._axstack .get (key )
917
- if ax is not None and isinstance (ax , projection_class ):
941
+ if isinstance (ax , projection_class ):
918
942
self .sca (ax )
919
943
return ax
920
944
@@ -988,15 +1012,14 @@ def add_subplot(self, *args, **kwargs):
988
1012
raise ValueError (msg )
989
1013
# make a key for the subplot (which includes the axes object id
990
1014
# in the hash)
991
- key = self . _make_key ( * args , ** kwargs )
1015
+ key = ( args , kwargs )
992
1016
else :
993
1017
projection_class , kwargs , key = process_projection_requirements (
994
1018
self , * args , ** kwargs )
995
1019
996
1020
# try to find the axes with this key in the stack
997
1021
ax = self ._axstack .get (key )
998
-
999
- if ax is not None :
1022
+ if ax :
1000
1023
if isinstance (ax , projection_class ):
1001
1024
# the axes already existed, so set it as active & return
1002
1025
self .sca (ax )
@@ -1496,7 +1519,7 @@ def _gci(self):
1496
1519
do not use elsewhere.
1497
1520
"""
1498
1521
# Look first for an image in the current Axes:
1499
- cax = self ._axstack .current_key_axes ()[ 1 ]
1522
+ ckey , cax = self ._axstack .current_key_axes ()
1500
1523
if cax is None :
1501
1524
return None
1502
1525
im = cax ._gci ()
0 commit comments