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,68 @@ def __contains__(self, a):
157
158
return a in self .as_list ()
158
159
159
160
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
+ def as_list (self ):
174
+ """Copy of the list of axes, in the order of insertion.
175
+ """
176
+ return self ._axes_ordered [:]
177
+
178
+ def get (self , key ):
179
+ """Find the axes corresponding to a key; defaults to `None`.
180
+ """
181
+ try :
182
+ return self ._axes [self ._keys .index (key )]
183
+ except ValueError :
184
+ return None
185
+
186
+ def current_key_axes (self ):
187
+ """Return the topmost key, axes pair, or `None, None` if empty.
188
+ """
189
+ return (self ._keys [- 1 ], self ._axes [- 1 ]) if self ._keys else (None , None )
190
+
191
+ def add (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
+ if ax in self ._axes_ordered :
197
+ return
198
+ self ._keys .append (key )
199
+ self ._axes .append (ax )
200
+ self ._axes_ordered .append (ax )
201
+
202
+ def bubble (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
+ del self ._keys [idx ], self ._axes [idx ]
209
+
210
+ def remove (self , ax ):
211
+ """Remove an axes and its corresponding key.
212
+ """
213
+ del self ._keys [self ._axes .index (ax )]
214
+ self ._axes .remove (ax )
215
+ self ._axes_ordered .remove (ax )
216
+
217
+ def clear (self ):
218
+ """Clear the stack.
219
+ """
220
+ del self ._keys [:], self ._axes [:], self ._axes_ordered [:]
221
+
222
+
160
223
class SubplotParams (object ):
161
224
"""
162
225
A class to hold the parameters for a subplot
@@ -350,7 +413,7 @@ def __init__(self,
350
413
self .subplotpars = subplotpars
351
414
self .set_tight_layout (tight_layout )
352
415
353
- self ._axstack = AxesStack () # track all figure axes and current axes
416
+ self ._axstack = _AxesStack () # track all figure axes and current axes
354
417
self .clf ()
355
418
self ._cachedRenderer = None
356
419
@@ -398,10 +461,8 @@ def show(self, warn=True):
398
461
"matplotlib is currently using a non-GUI backend, "
399
462
"so cannot show the figure" )
400
463
401
- def _get_axes (self ):
402
- return self ._axstack .as_list ()
403
-
404
- axes = property (fget = _get_axes , doc = "Read-only: list of axes in Figure" )
464
+ axes = property (lambda self : self ._axstack .as_list (),
465
+ doc = "Read-only: list of axes in Figure" )
405
466
406
467
def _get_dpi (self ):
407
468
return self ._dpi
@@ -812,36 +873,6 @@ def delaxes(self, a):
812
873
func (self )
813
874
self .stale = True
814
875
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
876
@docstring .dedent_interpd
846
877
def add_axes (self , * args , ** kwargs ):
847
878
"""
@@ -895,9 +926,9 @@ def add_axes(self, *args, **kwargs):
895
926
896
927
# shortcut the projection "key" modifications later on, if an axes
897
928
# with the exact args/kwargs exists, return it immediately.
898
- key = self . _make_key ( * args , ** kwargs )
929
+ key = ( args , kwargs )
899
930
ax = self ._axstack .get (key )
900
- if ax is not None :
931
+ if ax :
901
932
self .sca (ax )
902
933
return ax
903
934
@@ -914,7 +945,7 @@ def add_axes(self, *args, **kwargs):
914
945
# check that an axes of this type doesn't already exist, if it
915
946
# does, set it as active and return it
916
947
ax = self ._axstack .get (key )
917
- if ax is not None and isinstance (ax , projection_class ):
948
+ if isinstance (ax , projection_class ):
918
949
self .sca (ax )
919
950
return ax
920
951
@@ -988,15 +1019,14 @@ def add_subplot(self, *args, **kwargs):
988
1019
raise ValueError (msg )
989
1020
# make a key for the subplot (which includes the axes object id
990
1021
# in the hash)
991
- key = self . _make_key ( * args , ** kwargs )
1022
+ key = ( args , kwargs )
992
1023
else :
993
1024
projection_class , kwargs , key = process_projection_requirements (
994
1025
self , * args , ** kwargs )
995
1026
996
1027
# try to find the axes with this key in the stack
997
1028
ax = self ._axstack .get (key )
998
-
999
- if ax is not None :
1029
+ if ax :
1000
1030
if isinstance (ax , projection_class ):
1001
1031
# the axes already existed, so set it as active & return
1002
1032
self .sca (ax )
@@ -1496,7 +1526,7 @@ def _gci(self):
1496
1526
do not use elsewhere.
1497
1527
"""
1498
1528
# 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 ()
1500
1530
if cax is None :
1501
1531
return None
1502
1532
im = cax ._gci ()
0 commit comments