@@ -52,9 +52,10 @@ def default_units(x, axis):
52
52
53
53
class AxisInfo (object ):
54
54
"""
55
- Information to support default axis labeling, tick labeling, and
56
- default limits. An instance of this class must be returned by
57
- :meth:`ConversionInterface.axisinfo`.
55
+ Information to support default axis labeling, tick labeling, and limits.
56
+
57
+ An instance of this class must be returned by
58
+ `ConversionInterface.axisinfo`.
58
59
"""
59
60
def __init__ (self , majloc = None , minloc = None ,
60
61
majfmt = None , minfmt = None , label = None ,
@@ -93,8 +94,7 @@ class ConversionInterface(object):
93
94
@staticmethod
94
95
def axisinfo (unit , axis ):
95
96
"""
96
- Return an `~units.AxisInfo` instance for the axis with the
97
- specified units.
97
+ Return an `~units.AxisInfo` for the axis with the specified units.
98
98
"""
99
99
return None
100
100
@@ -109,19 +109,19 @@ def default_units(x, axis):
109
109
def convert (obj , unit , axis ):
110
110
"""
111
111
Convert *obj* using *unit* for the specified *axis*.
112
- If *obj* is a sequence, return the converted sequence.
113
- The output must be a sequence of scalars that can be used by the numpy
114
- array layer.
112
+
113
+ If *obj* is a sequence, return the converted sequence. The output must
114
+ be a sequence of scalars that can be used by the numpy array layer.
115
115
"""
116
116
return obj
117
117
118
118
@staticmethod
119
119
def is_numlike (x ):
120
120
"""
121
- The Matplotlib datalim, autoscaling, locators etc work with
122
- scalars which are the units converted to floats given the
123
- current unit. The converter may be passed these floats, or
124
- arrays of them, even when units are set.
121
+ The Matplotlib datalim, autoscaling, locators etc work with scalars
122
+ which are the units converted to floats given the current unit. The
123
+ converter may be passed these floats, or arrays of them, even when
124
+ units are set.
125
125
"""
126
126
if iterable (x ):
127
127
for thisx in x :
@@ -131,66 +131,28 @@ def is_numlike(x):
131
131
132
132
133
133
class Registry (dict ):
134
- """
135
- A register that maps types to conversion interfaces.
136
- """
137
- def __init__ (self ):
138
- dict .__init__ (self )
139
- self ._cached = {}
134
+ """Register types with conversion interface."""
140
135
141
136
def get_converter (self , x ):
142
- """
143
- Get the converter for data that has the same type as *x*. If no
144
- converters are registered for *x*, returns ``None``.
145
- """
146
-
147
- if not len (self ):
148
- return None # nothing registered
149
- # DISABLED idx = id(x)
150
- # DISABLED cached = self._cached.get(idx)
151
- # DISABLED if cached is not None: return cached
152
-
153
- converter = None
154
- classx = getattr (x , '__class__' , None )
155
-
156
- if classx is not None :
157
- converter = self .get (classx )
158
-
159
- # If x is an array, look inside the array for data with units
160
- if isinstance (x , np .ndarray ) and x .size :
161
- xravel = x .ravel ()
137
+ """Get the converter interface instance for *x*, or None."""
138
+ if isinstance (x , np .ndarray ):
139
+ # In case x in a masked array, access the underlying data (only its
140
+ # type matters). If x is a regular ndarray, getdata() just returns
141
+ # the array itself.
142
+ x = np .ma .getdata (x ).ravel ()
143
+ try :
144
+ return self [type (x )]
145
+ except KeyError :
162
146
try :
163
- # pass the first value of x that is not masked back to
164
- # get_converter
165
- if not np .all (xravel .mask ):
166
- # some elements are not masked
167
- converter = self .get_converter (
168
- xravel [np .argmin (xravel .mask )])
169
- return converter
170
- except AttributeError :
171
- # not a masked_array
172
- # Make sure we don't recurse forever -- it's possible for
173
- # ndarray subclasses to continue to return subclasses and
174
- # not ever return a non-subclass for a single element.
175
- next_item = xravel [0 ]
176
- if (not isinstance (next_item , np .ndarray ) or
177
- next_item .shape != x .shape ):
178
- converter = self .get_converter (next_item )
179
- return converter
180
-
181
- # If we haven't found a converter yet, try to get the first element
182
- if converter is None :
183
- try :
184
- thisx = safe_first_element (x )
147
+ first = safe_first_element (x )
185
148
except (TypeError , StopIteration ):
186
149
pass
187
150
else :
188
- if classx and classx != getattr (thisx , '__class__' , None ):
189
- converter = self .get_converter (thisx )
190
- return converter
191
-
192
- # DISABLED self._cached[idx] = converter
193
- return converter
151
+ # Avoid infinite recursion for pathological iterables for which
152
+ # indexing returns instances of the same iterable class.
153
+ if type (first ) is not type (x ):
154
+ return self .get_converter (first )
155
+ return None
194
156
195
157
196
158
registry = Registry ()
0 commit comments