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

Skip to content

Commit 244fd21

Browse files
committed
MNT: add a warning if a categroical string array is all convertible to numbers or dates
1 parent 56243e9 commit 244fd21

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

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

@@ -168,6 +170,20 @@ def __init__(self, data=None):
168170
if data is not None:
169171
self.update(data)
170172

173+
@staticmethod
174+
def _str_is_convertable(val):
175+
"""
176+
Helper method to see if string can be cast to float or parsed as date.
177+
"""
178+
try:
179+
float(val)
180+
except ValueError:
181+
try:
182+
dateutil.parser.parse(val)
183+
except ValueError:
184+
return False
185+
return True
186+
171187
def update(self, data):
172188
"""Maps new values to integer identifiers.
173189
@@ -183,11 +199,20 @@ def update(self, data):
183199
"""
184200
data = np.atleast_1d(np.array(data, dtype=object))
185201

202+
convertable = True
186203
for val in OrderedDict.fromkeys(data):
204+
# OrderedDict just iterates over unique values in data.
187205
if not isinstance(val, (str, bytes)):
188206
raise TypeError("{val!r} is not a string".format(val=val))
207+
# check if we can convert string to number or date...
208+
convertable = (convertable and self._str_is_convertable(val))
189209
if val not in self._mapping:
190210
self._mapping[val] = next(self._counter)
211+
if convertable:
212+
cbook._warn_external('using category units to plot a list of '
213+
'strings that is a;; floats or parsable as dates. '
214+
'If you do not mean these to be categories, cast '
215+
'to the approriate data type before plotting.')
191216

192217

193218
# Connects the convertor to matplotlib

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)