12
12
"""
13
13
14
14
from collections import OrderedDict
15
+ import dateutil .parser
15
16
import itertools
17
+ import logging
16
18
17
19
import numpy as np
18
20
21
+ import matplotlib .cbook as cbook
19
22
import matplotlib .units as units
20
23
import matplotlib .ticker as ticker
21
24
22
25
26
+ _log = logging .getLogger (__name__ )
27
+
28
+
23
29
class StrCategoryConverter (units .ConversionInterface ):
24
30
@staticmethod
25
31
def convert (value , unit , axis ):
@@ -168,6 +174,23 @@ def __init__(self, data=None):
168
174
if data is not None :
169
175
self .update (data )
170
176
177
+ @staticmethod
178
+ def _strs_are_convertible (vals ):
179
+ """
180
+ Helper method to see if list of strings can all be cast to float or
181
+ parsed as date.
182
+ """
183
+
184
+ for val in vals :
185
+ try :
186
+ float (val )
187
+ except ValueError :
188
+ try :
189
+ dateutil .parser .parse (val )
190
+ except ValueError :
191
+ return False
192
+ return True
193
+
171
194
def update (self , data ):
172
195
"""Maps new values to integer identifiers.
173
196
@@ -184,10 +207,17 @@ def update(self, data):
184
207
data = np .atleast_1d (np .array (data , dtype = object ))
185
208
186
209
for val in OrderedDict .fromkeys (data ):
210
+ # OrderedDict just iterates over unique values in data.
187
211
if not isinstance (val , (str , bytes )):
188
212
raise TypeError ("{val!r} is not a string" .format (val = val ))
189
213
if val not in self ._mapping :
190
214
self ._mapping [val ] = next (self ._counter )
215
+ # check if we can convert all strings to number or date...
216
+ if self ._strs_are_convertible (data ):
217
+ _log .info ('using category units to plot a list of '
218
+ 'strings that is all floats or parsable as dates. '
219
+ 'If you do not mean these to be categories, cast '
220
+ 'to the approriate data type before plotting.' )
191
221
192
222
193
223
# Connects the convertor to matplotlib
0 commit comments