Skip to content

Commit b6c8195

Browse files
Debian Science Teamrebecca-palmer
Debian Science Team
authored andcommitted
Matplotlib 3.3 compatibility fixups
Author: Tom Augspurger, Saul Shanabrook, Rebecca N. Palmer <[email protected]> Bug-Debian: https://bugs.debian.org/966393 Origin: (partly) upstream commits 41022a8 + 00ea10c Forwarded: no Gbp-Pq: Name matplotlib33_compat.patch
1 parent 9dfec21 commit b6c8195

File tree

8 files changed

+34
-41
lines changed

8 files changed

+34
-41
lines changed

pandas/plotting/_matplotlib/boxplot.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ def plot_group(keys, values, ax):
288288
if fontsize is not None:
289289
ax.tick_params(axis="both", labelsize=fontsize)
290290
if kwds.get("vert", 1):
291+
ticks = ax.get_xticks()
292+
if len(ticks) != len(keys):
293+
i, remainder = divmod(len(ticks), len(keys))
294+
assert remainder == 0, remainder
295+
keys *= i
291296
ax.set_xticklabels(keys, rotation=rot)
292297
else:
293298
ax.set_yticklabels(keys, rotation=rot)

pandas/plotting/_matplotlib/compat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ def inner():
2121
_mpl_ge_3_0_0 = _mpl_version("3.0.0", operator.ge)
2222
_mpl_ge_3_1_0 = _mpl_version("3.1.0", operator.ge)
2323
_mpl_ge_3_2_0 = _mpl_version("3.2.0", operator.ge)
24+
_mpl_ge_3_3_0 = _mpl_version("3.3.0", operator.ge)

pandas/plotting/_matplotlib/converter.py

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from pandas._libs.tslibs.frequencies import FreqGroup, get_freq
1616

1717
from pandas.core.dtypes.common import (
18-
is_datetime64_ns_dtype,
1918
is_float,
2019
is_float_dtype,
2120
is_integer,
@@ -246,19 +245,6 @@ def get_datevalue(date, freq):
246245
raise ValueError(f"Unrecognizable date '{date}'")
247246

248247

249-
def _dt_to_float_ordinal(dt):
250-
"""
251-
Convert :mod:`datetime` to the Gregorian date as UTC float days,
252-
preserving hours, minutes, seconds and microseconds. Return value
253-
is a :func:`float`.
254-
"""
255-
if isinstance(dt, (np.ndarray, Index, ABCSeries)) and is_datetime64_ns_dtype(dt):
256-
base = dates.epoch2num(dt.asi8 / 1.0e9)
257-
else:
258-
base = dates.date2num(dt)
259-
return base
260-
261-
262248
# Datetime Conversion
263249
class DatetimeConverter(dates.DateConverter):
264250
@staticmethod
@@ -274,15 +260,11 @@ def convert(values, unit, axis):
274260
def _convert_1d(values, unit, axis):
275261
def try_parse(values):
276262
try:
277-
return _dt_to_float_ordinal(tools.to_datetime(values))
263+
return dates.date2num(tools.to_datetime(values))
278264
except Exception:
279265
return values
280266

281-
if isinstance(values, (datetime, pydt.date)):
282-
return _dt_to_float_ordinal(values)
283-
elif isinstance(values, np.datetime64):
284-
return _dt_to_float_ordinal(tslibs.Timestamp(values))
285-
elif isinstance(values, pydt.time):
267+
if isinstance(values, (datetime, pydt.date, np.datetime64, pydt.time)):
286268
return dates.date2num(values)
287269
elif is_integer(values) or is_float(values):
288270
return values
@@ -303,12 +285,10 @@ def try_parse(values):
303285

304286
try:
305287
values = tools.to_datetime(values)
306-
if isinstance(values, Index):
307-
values = _dt_to_float_ordinal(values)
308-
else:
309-
values = [_dt_to_float_ordinal(x) for x in values]
310288
except Exception:
311-
values = _dt_to_float_ordinal(values)
289+
pass
290+
291+
values = dates.date2num(values)
312292

313293
return values
314294

@@ -429,8 +409,8 @@ def __call__(self):
429409
interval = self._get_interval()
430410
freq = f"{interval}L"
431411
tz = self.tz.tzname(None)
432-
st = _from_ordinal(dates.date2num(dmin)) # strip tz
433-
ed = _from_ordinal(dates.date2num(dmax))
412+
st = dmin.replace(tzinfo=None)
413+
ed = dmin.replace(tzinfo=None)
434414
all_dates = date_range(start=st, end=ed, freq=freq, tz=tz).astype(object)
435415

436416
try:

pandas/tests/plotting/test_converter.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
pass
2828

2929
pytest.importorskip("matplotlib.pyplot")
30+
dates = pytest.importorskip("matplotlib.dates")
3031

3132

3233
def test_registry_mpl_resets():
@@ -146,7 +147,7 @@ def test_convert_accepts_unicode(self):
146147

147148
def test_conversion(self):
148149
rs = self.dtc.convert(["2012-1-1"], None, None)[0]
149-
xp = datetime(2012, 1, 1).toordinal()
150+
xp = dates.date2num(datetime(2012, 1, 1))
150151
assert rs == xp
151152

152153
rs = self.dtc.convert("2012-1-1", None, None)
@@ -155,9 +156,6 @@ def test_conversion(self):
155156
rs = self.dtc.convert(date(2012, 1, 1), None, None)
156157
assert rs == xp
157158

158-
rs = self.dtc.convert(datetime(2012, 1, 1).toordinal(), None, None)
159-
assert rs == xp
160-
161159
rs = self.dtc.convert("2012-1-1", None, None)
162160
assert rs == xp
163161

pandas/tests/plotting/test_datetimelike.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def test_business_freq(self):
306306
bts = tm.makePeriodSeries()
307307
_, ax = self.plt.subplots()
308308
bts.plot(ax=ax)
309-
assert ax.get_lines()[0].get_xydata()[0, 0] == bts.index[0].ordinal
309+
310310
idx = ax.get_lines()[0].get_xdata()
311311
assert PeriodIndex(data=idx).freqstr == "B"
312312

@@ -1262,6 +1262,8 @@ def test_mpl_nopandas(self):
12621262
@pytest.mark.slow
12631263
def test_irregular_ts_shared_ax_xlim(self):
12641264
# GH 2960
1265+
from pandas.plotting._matplotlib.converter import DatetimeConverter
1266+
12651267
ts = tm.makeTimeSeries()[:20]
12661268
ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
12671269

@@ -1272,8 +1274,8 @@ def test_irregular_ts_shared_ax_xlim(self):
12721274

12731275
# check that axis limits are correct
12741276
left, right = ax.get_xlim()
1275-
assert left <= ts_irregular.index.min().toordinal()
1276-
assert right >= ts_irregular.index.max().toordinal()
1277+
assert left <= DatetimeConverter.convert(ts_irregular.index.min(), "", ax)
1278+
assert right >= DatetimeConverter.convert(ts_irregular.index.max(), "", ax)
12771279

12781280
@pytest.mark.slow
12791281
def test_secondary_y_non_ts_xlim(self):
@@ -1328,6 +1330,8 @@ def test_secondary_y_mixed_freq_ts_xlim(self):
13281330
@pytest.mark.slow
13291331
def test_secondary_y_irregular_ts_xlim(self):
13301332
# GH 3490 - irregular-timeseries with secondary y
1333+
from pandas.plotting._matplotlib.converter import DatetimeConverter
1334+
13311335
ts = tm.makeTimeSeries()[:20]
13321336
ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
13331337

@@ -1339,8 +1343,8 @@ def test_secondary_y_irregular_ts_xlim(self):
13391343
ts_irregular[:5].plot(ax=ax)
13401344

13411345
left, right = ax.get_xlim()
1342-
assert left <= ts_irregular.index.min().toordinal()
1343-
assert right >= ts_irregular.index.max().toordinal()
1346+
assert left <= DatetimeConverter.convert(ts_irregular.index.min(), "", ax)
1347+
assert right >= DatetimeConverter.convert(ts_irregular.index.max(), "", ax)
13441348

13451349
def test_plot_outofbounds_datetime(self):
13461350
# 2579 - checking this does not raise
@@ -1444,7 +1448,7 @@ def test_overlapping_datetime(self):
14441448
s2.plot(ax=ax)
14451449
s1.plot(ax=ax)
14461450

1447-
@pytest.mark.xfail(reason="GH9053 matplotlib does not use ax.xaxis.converter")
1451+
@pytest.mark.xfail(reason="GH9053 matplotlib does not use ax.xaxis.converter", strict=False)
14481452
def test_add_matplotlib_datetime64(self):
14491453
# GH9053 - ensure that a plot with PeriodConverter still understands
14501454
# datetime64 data. This still fails because matplotlib overrides the

pandas/tests/plotting/test_frame.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,7 @@ def test_boxplot(self):
15311531
ax.xaxis.get_ticklocs(), np.arange(1, len(numeric_cols) + 1)
15321532
)
15331533
assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
1534+
tm.close()
15341535

15351536
axes = series.plot.box(rot=40)
15361537
self._check_ticks_props(axes, xrot=40, yrot=0)

pandas/tests/plotting/test_series.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,14 @@ def test_rotation(self):
276276
self._check_ticks_props(axes, xrot=30)
277277

278278
def test_irregular_datetime(self):
279+
from pandas.plotting._matplotlib.converter import DatetimeConverter
280+
279281
rng = date_range("1/1/2000", "3/1/2000")
280282
rng = rng[[0, 1, 2, 3, 5, 9, 10, 11, 12]]
281283
ser = Series(randn(len(rng)), rng)
282284
_, ax = self.plt.subplots()
283285
ax = ser.plot(ax=ax)
284-
xp = datetime(1999, 1, 1).toordinal()
286+
xp = DatetimeConverter.convert(datetime(1999, 1, 1), "", ax)
285287
ax.set_xlim("1/1/1999", "1/1/2001")
286288
assert xp == ax.get_xlim()[0]
287289

@@ -686,11 +688,13 @@ def test_kind_both_ways(self):
686688
kinds = (
687689
plotting.PlotAccessor._common_kinds + plotting.PlotAccessor._series_kinds
688690
)
689-
_, ax = self.plt.subplots()
690691
for kind in kinds:
691-
692+
_, ax = self.plt.subplots()
692693
s.plot(kind=kind, ax=ax)
694+
self.plt.close()
695+
_, ax = self.plt.subplots()
693696
getattr(s.plot, kind)()
697+
self.plt.close()
694698

695699
@pytest.mark.slow
696700
def test_invalid_plot_data(self):

pandas/util/_test_decorators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def safe_import(mod_name: str, min_version: Optional[str] = None):
9494
def _skip_if_no_mpl():
9595
mod = safe_import("matplotlib")
9696
if mod:
97-
mod.use("Agg", warn=True)
97+
mod.use("Agg")
9898
else:
9999
return True
100100

0 commit comments

Comments
 (0)