1212"""
1313
1414from collections import OrderedDict
15+ import dateutil .parser
1516import itertools
17+ import logging
1618
1719import numpy as np
1820
21+ import matplotlib .cbook as cbook
1922import matplotlib .units as units
2023import matplotlib .ticker as ticker
2124
2225
26+ _log = logging .getLogger (__name__ )
27+
28+
2329class StrCategoryConverter (units .ConversionInterface ):
2430 @staticmethod
2531 def convert (value , unit , axis ):
@@ -168,6 +174,23 @@ def __init__(self, data=None):
168174 if data is not None :
169175 self .update (data )
170176
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+
171194 def update (self , data ):
172195 """Maps new values to integer identifiers.
173196
@@ -184,10 +207,17 @@ def update(self, data):
184207 data = np .atleast_1d (np .array (data , dtype = object ))
185208
186209 for val in OrderedDict .fromkeys (data ):
210+ # OrderedDict just iterates over unique values in data.
187211 if not isinstance (val , (str , bytes )):
188212 raise TypeError ("{val!r} is not a string" .format (val = val ))
189213 if val not in self ._mapping :
190214 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.' )
191221
192222
193223# Connects the convertor to matplotlib
0 commit comments