Matplotlib 3.3 compatibility fixups
authorDebian Science Team <debian-science-maintainers@lists.alioth.debian.org>
Wed, 26 Aug 2020 21:34:50 +0000 (22:34 +0100)
committerRebecca N. Palmer <rebecca_palmer@zoho.com>
Wed, 26 Aug 2020 21:34:50 +0000 (22:34 +0100)
Author: Tom Augspurger, Saul Shanabrook, Rebecca N. Palmer <rebecca_palmer@zoho.com>
Bug-Debian: https://bugs.debian.org/966393
Origin: (partly) upstream commits 41022a8 + 00ea10c
Forwarded: no

Gbp-Pq: Name matplotlib33_compat.patch

pandas/plotting/_matplotlib/boxplot.py
pandas/plotting/_matplotlib/compat.py
pandas/plotting/_matplotlib/converter.py
pandas/tests/plotting/test_converter.py
pandas/tests/plotting/test_datetimelike.py
pandas/tests/plotting/test_frame.py
pandas/tests/plotting/test_series.py
pandas/util/_test_decorators.py

index deeeb0016142c40d0629ba25cdecaedab4a53865..3db667219e8aaaf840581d2484c03023af2126e5 100644 (file)
@@ -288,6 +288,11 @@ def boxplot(
         if fontsize is not None:
             ax.tick_params(axis="both", labelsize=fontsize)
         if kwds.get("vert", 1):
+            ticks = ax.get_xticks()
+            if len(ticks) != len(keys):
+                i, remainder = divmod(len(ticks), len(keys))
+                assert remainder == 0, remainder
+                keys *= i
             ax.set_xticklabels(keys, rotation=rot)
         else:
             ax.set_yticklabels(keys, rotation=rot)
index f2c5032112bc9a4f58127fe75241bc077bece471..7f107f18eca259e0e2453b802f9e6397659b714f 100644 (file)
@@ -21,3 +21,4 @@ _mpl_ge_2_2_3 = _mpl_version("2.2.3", operator.ge)
 _mpl_ge_3_0_0 = _mpl_version("3.0.0", operator.ge)
 _mpl_ge_3_1_0 = _mpl_version("3.1.0", operator.ge)
 _mpl_ge_3_2_0 = _mpl_version("3.2.0", operator.ge)
+_mpl_ge_3_3_0 = _mpl_version("3.3.0", operator.ge)
index 5b37ebb42aeccd5da354fae133ccf48aef08af48..c0b8b3e6264f585766759c7157af0e6347956118 100644 (file)
@@ -15,7 +15,6 @@ from pandas._libs.tslibs import resolution
 from pandas._libs.tslibs.frequencies import FreqGroup, get_freq
 
 from pandas.core.dtypes.common import (
-    is_datetime64_ns_dtype,
     is_float,
     is_float_dtype,
     is_integer,
@@ -246,19 +245,6 @@ def get_datevalue(date, freq):
     raise ValueError(f"Unrecognizable date '{date}'")
 
 
-def _dt_to_float_ordinal(dt):
-    """
-    Convert :mod:`datetime` to the Gregorian date as UTC float days,
-    preserving hours, minutes, seconds and microseconds.  Return value
-    is a :func:`float`.
-    """
-    if isinstance(dt, (np.ndarray, Index, ABCSeries)) and is_datetime64_ns_dtype(dt):
-        base = dates.epoch2num(dt.asi8 / 1.0e9)
-    else:
-        base = dates.date2num(dt)
-    return base
-
-
 # Datetime Conversion
 class DatetimeConverter(dates.DateConverter):
     @staticmethod
@@ -274,15 +260,11 @@ class DatetimeConverter(dates.DateConverter):
     def _convert_1d(values, unit, axis):
         def try_parse(values):
             try:
-                return _dt_to_float_ordinal(tools.to_datetime(values))
+                return dates.date2num(tools.to_datetime(values))
             except Exception:
                 return values
 
-        if isinstance(values, (datetime, pydt.date)):
-            return _dt_to_float_ordinal(values)
-        elif isinstance(values, np.datetime64):
-            return _dt_to_float_ordinal(tslibs.Timestamp(values))
-        elif isinstance(values, pydt.time):
+        if isinstance(values, (datetime, pydt.date, np.datetime64, pydt.time)):
             return dates.date2num(values)
         elif is_integer(values) or is_float(values):
             return values
@@ -303,12 +285,10 @@ class DatetimeConverter(dates.DateConverter):
 
             try:
                 values = tools.to_datetime(values)
-                if isinstance(values, Index):
-                    values = _dt_to_float_ordinal(values)
-                else:
-                    values = [_dt_to_float_ordinal(x) for x in values]
             except Exception:
-                values = _dt_to_float_ordinal(values)
+                pass
+
+            values = dates.date2num(values)
 
         return values
 
@@ -429,8 +409,8 @@ class MilliSecondLocator(dates.DateLocator):
         interval = self._get_interval()
         freq = f"{interval}L"
         tz = self.tz.tzname(None)
-        st = _from_ordinal(dates.date2num(dmin))  # strip tz
-        ed = _from_ordinal(dates.date2num(dmax))
+        st = dmin.replace(tzinfo=None)
+        ed = dmin.replace(tzinfo=None)
         all_dates = date_range(start=st, end=ed, freq=freq, tz=tz).astype(object)
 
         try:
index e54f4784e9c4fa31fee0353347cf2ed16fc45b12..891e094b3d3f4950d40e7f0a528bd6cef8b2f1e3 100644 (file)
@@ -27,6 +27,7 @@ except ImportError:
     pass
 
 pytest.importorskip("matplotlib.pyplot")
+dates = pytest.importorskip("matplotlib.dates")
 
 
 def test_registry_mpl_resets():
@@ -146,7 +147,7 @@ class TestDateTimeConverter:
 
     def test_conversion(self):
         rs = self.dtc.convert(["2012-1-1"], None, None)[0]
-        xp = datetime(2012, 1, 1).toordinal()
+        xp = dates.date2num(datetime(2012, 1, 1))
         assert rs == xp
 
         rs = self.dtc.convert("2012-1-1", None, None)
@@ -155,9 +156,6 @@ class TestDateTimeConverter:
         rs = self.dtc.convert(date(2012, 1, 1), None, None)
         assert rs == xp
 
-        rs = self.dtc.convert(datetime(2012, 1, 1).toordinal(), None, None)
-        assert rs == xp
-
         rs = self.dtc.convert("2012-1-1", None, None)
         assert rs == xp
 
index bd5781cb08816c98edc944a223c1df7134785c30..9fec3cf2e260e6ea368f62fa54cdc5049f7574b2 100644 (file)
@@ -306,7 +306,7 @@ class TestTSPlot(TestPlotBase):
         bts = tm.makePeriodSeries()
         _, ax = self.plt.subplots()
         bts.plot(ax=ax)
-        assert ax.get_lines()[0].get_xydata()[0, 0] == bts.index[0].ordinal
+
         idx = ax.get_lines()[0].get_xdata()
         assert PeriodIndex(data=idx).freqstr == "B"
 
@@ -1262,6 +1262,8 @@ class TestTSPlot(TestPlotBase):
     @pytest.mark.slow
     def test_irregular_ts_shared_ax_xlim(self):
         # GH 2960
+        from pandas.plotting._matplotlib.converter import DatetimeConverter
+
         ts = tm.makeTimeSeries()[:20]
         ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
 
@@ -1272,8 +1274,8 @@ class TestTSPlot(TestPlotBase):
 
         # check that axis limits are correct
         left, right = ax.get_xlim()
-        assert left <= ts_irregular.index.min().toordinal()
-        assert right >= ts_irregular.index.max().toordinal()
+        assert left <= DatetimeConverter.convert(ts_irregular.index.min(), "", ax)
+        assert right >= DatetimeConverter.convert(ts_irregular.index.max(), "", ax)
 
     @pytest.mark.slow
     def test_secondary_y_non_ts_xlim(self):
@@ -1328,6 +1330,8 @@ class TestTSPlot(TestPlotBase):
     @pytest.mark.slow
     def test_secondary_y_irregular_ts_xlim(self):
         # GH 3490 - irregular-timeseries with secondary y
+        from pandas.plotting._matplotlib.converter import DatetimeConverter
+
         ts = tm.makeTimeSeries()[:20]
         ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
 
@@ -1339,8 +1343,8 @@ class TestTSPlot(TestPlotBase):
         ts_irregular[:5].plot(ax=ax)
 
         left, right = ax.get_xlim()
-        assert left <= ts_irregular.index.min().toordinal()
-        assert right >= ts_irregular.index.max().toordinal()
+        assert left <= DatetimeConverter.convert(ts_irregular.index.min(), "", ax)
+        assert right >= DatetimeConverter.convert(ts_irregular.index.max(), "", ax)
 
     def test_plot_outofbounds_datetime(self):
         # 2579 - checking this does not raise
@@ -1444,7 +1448,7 @@ class TestTSPlot(TestPlotBase):
         s2.plot(ax=ax)
         s1.plot(ax=ax)
 
-    @pytest.mark.xfail(reason="GH9053 matplotlib does not use ax.xaxis.converter")
+    @pytest.mark.xfail(reason="GH9053 matplotlib does not use ax.xaxis.converter", strict=False)
     def test_add_matplotlib_datetime64(self):
         # GH9053 - ensure that a plot with PeriodConverter still understands
         # datetime64 data. This still fails because matplotlib overrides the
index ba6582126ca8424dd65f1e061ece1355a3417159..1cbba78b44dfa30685c6534b3f71cc2a78391252 100644 (file)
@@ -1531,6 +1531,7 @@ class TestDataFramePlots(TestPlotBase):
             ax.xaxis.get_ticklocs(), np.arange(1, len(numeric_cols) + 1)
         )
         assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
+        tm.close()
 
         axes = series.plot.box(rot=40)
         self._check_ticks_props(axes, xrot=40, yrot=0)
index 8463f30bee8f0f5ab4fd44b22907f8e36a1f84a2..bb6e6984e110e5bc668d50955ec78f9a0a3497c9 100644 (file)
@@ -276,12 +276,14 @@ class TestSeriesPlots(TestPlotBase):
         self._check_ticks_props(axes, xrot=30)
 
     def test_irregular_datetime(self):
+        from pandas.plotting._matplotlib.converter import DatetimeConverter
+
         rng = date_range("1/1/2000", "3/1/2000")
         rng = rng[[0, 1, 2, 3, 5, 9, 10, 11, 12]]
         ser = Series(randn(len(rng)), rng)
         _, ax = self.plt.subplots()
         ax = ser.plot(ax=ax)
-        xp = datetime(1999, 1, 1).toordinal()
+        xp = DatetimeConverter.convert(datetime(1999, 1, 1), "", ax)
         ax.set_xlim("1/1/1999", "1/1/2001")
         assert xp == ax.get_xlim()[0]
 
@@ -686,11 +688,13 @@ class TestSeriesPlots(TestPlotBase):
         kinds = (
             plotting.PlotAccessor._common_kinds + plotting.PlotAccessor._series_kinds
         )
-        _, ax = self.plt.subplots()
         for kind in kinds:
-
+            _, ax = self.plt.subplots()
             s.plot(kind=kind, ax=ax)
+            self.plt.close()
+            _, ax = self.plt.subplots()
             getattr(s.plot, kind)()
+            self.plt.close()
 
     @pytest.mark.slow
     def test_invalid_plot_data(self):
index d8804994af426b0d015a3120c5ed95ffc2fc8bfb..eb0f8022034c90bdd60df7180e5ea25b9989c67f 100644 (file)
@@ -94,7 +94,7 @@ xfail_non_writeable = pytest.mark.xfail(
 def _skip_if_no_mpl():
     mod = safe_import("matplotlib")
     if mod:
-        mod.use("Agg", warn=True)
+        mod.use("Agg")
     else:
         return True