Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5797522

Browse files
committed
MNT: add a warning if a categroical string array is all convertible to numbers or dates
1 parent 7b40990 commit 5797522

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

lib/matplotlib/category.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
"""
1313

1414
from collections import OrderedDict
15+
import dateutil.parser
1516
import itertools
1617

1718
import numpy as np
1819

20+
import matplotlib.cbook as cbook
1921
import matplotlib.units as units
2022
import matplotlib.ticker as ticker
2123

@@ -174,6 +176,20 @@ def __init__(self, data=None):
174176
if data is not None:
175177
self.update(data)
176178

179+
@staticmethod
180+
def _str_is_convertable(val):
181+
"""
182+
Helper method to see if string can be cast to float or parsed as date.
183+
"""
184+
try:
185+
float(val)
186+
except ValueError:
187+
try:
188+
dateutil.parser.parse(val)
189+
except ValueError:
190+
return False
191+
return True
192+
177193
def update(self, data):
178194
"""Maps new values to integer identifiers.
179195
@@ -189,11 +205,20 @@ def update(self, data):
189205
"""
190206
data = np.atleast_1d(np.array(data, dtype=object))
191207

208+
convertable = True
192209
for val in OrderedDict.fromkeys(data):
210+
# OrderedDict just iterates over unique values in data.
193211
if not isinstance(val, (str, bytes)):
194212
raise TypeError("{val!r} is not a string".format(val=val))
213+
# check if we can convert string to number or date...
214+
convertable = (convertable and self._str_is_convertable(val))
195215
if val not in self._mapping:
196216
self._mapping[val] = next(self._counter)
217+
if convertable:
218+
cbook._warn_external('using category units to plot a list of '
219+
'strings that is a;; floats or parsable as dates. '
220+
'If you do not mean these to be categories, cast '
221+
'to the approriate data type before plotting.')
197222

198223

199224
# Register the converter with Matplotlib's unit framework

lib/matplotlib/tests/test_category.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ class TestPlotNumlike(object):
203203
@pytest.mark.parametrize("ndata", numlike_data, ids=numlike_ids)
204204
def test_plot_numlike(self, ax, plotter, ndata):
205205
counts = np.array([4, 6, 5])
206-
plotter(ax, ndata, counts)
206+
with pytest.warns(UserWarning, match='using category units to plot'):
207+
plotter(ax, ndata, counts)
207208
axis_test(ax.xaxis, ndata)
208209

209210

@@ -261,12 +262,14 @@ def test_update_plot(self, ax, plotter):
261262

262263
PLOT_BROKEN_IDS = ["scatter", "plot", "bar"]
263264

265+
@pytest.mark.filterwarnings('ignore::UserWarning')
264266
@pytest.mark.parametrize("plotter", PLOT_BROKEN_LIST, ids=PLOT_BROKEN_IDS)
265267
@pytest.mark.parametrize("xdata", fvalues, ids=fids)
266268
def test_mixed_type_exception(self, ax, plotter, xdata):
267269
with pytest.raises(TypeError):
268270
plotter(ax, xdata, [1, 2])
269271

272+
@pytest.mark.filterwarnings('ignore::UserWarning')
270273
@pytest.mark.parametrize("plotter", PLOT_BROKEN_LIST, ids=PLOT_BROKEN_IDS)
271274
@pytest.mark.parametrize("xdata", fvalues, ids=fids)
272275
def test_mixed_type_update_exception(self, ax, plotter, xdata):

0 commit comments

Comments
 (0)