Skip to content

Commit

Permalink
BUG: Silence Period[B] warnings in plotting code (#55138)
Browse files Browse the repository at this point in the history
* Silence `Period[B]` warnings in plotting code

* Add issue number and removal TODO

* Add entry for issue `#55138` to `v2.1.2.rst`

---------

Co-authored-by: torext <noreply>
  • Loading branch information
torext authored Oct 3, 2023
1 parent 7e68183 commit 6e6a683
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 18 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.1.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Bug fixes
~~~~~~~~~
- Fixed bug in :meth:`DataFrame.resample` not respecting ``closed`` and ``label`` arguments for :class:`~pandas.tseries.offsets.BusinessDay` (:issue:`55282`)
- Fixed bug in :meth:`DataFrame.resample` where bin edges were not correct for :class:`~pandas.tseries.offsets.BusinessDay` (:issue:`55281`)
- Silence ``Period[B]`` warnings introduced by :issue:`53446` during normal plotting activity (:issue:`55138`)
-

.. ---------------------------------------------------------------------------
Expand Down
61 changes: 43 additions & 18 deletions pandas/plotting/_matplotlib/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Any,
cast,
)
import warnings

import matplotlib.dates as mdates
from matplotlib.ticker import (
Expand Down Expand Up @@ -239,18 +240,29 @@ def _convert_1d(values, units, axis):
if not hasattr(axis, "freq"):
raise TypeError("Axis must have `freq` set to convert to Periods")
valid_types = (str, datetime, Period, pydt.date, pydt.time, np.datetime64)
if isinstance(values, valid_types) or is_integer(values) or is_float(values):
return get_datevalue(values, axis.freq)
elif isinstance(values, PeriodIndex):
return values.asfreq(axis.freq).asi8
elif isinstance(values, Index):
return values.map(lambda x: get_datevalue(x, axis.freq))
elif lib.infer_dtype(values, skipna=False) == "period":
# https://github.com/pandas-dev/pandas/issues/24304
# convert ndarray[period] -> PeriodIndex
return PeriodIndex(values, freq=axis.freq).asi8
elif isinstance(values, (list, tuple, np.ndarray, Index)):
return [get_datevalue(x, axis.freq) for x in values]
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", "Period with BDay freq is deprecated", category=FutureWarning
)
warnings.filterwarnings(
"ignore", r"PeriodDtype\[B\] is deprecated", category=FutureWarning
)
if (
isinstance(values, valid_types)
or is_integer(values)
or is_float(values)
):
return get_datevalue(values, axis.freq)
elif isinstance(values, PeriodIndex):
return values.asfreq(axis.freq).asi8
elif isinstance(values, Index):
return values.map(lambda x: get_datevalue(x, axis.freq))
elif lib.infer_dtype(values, skipna=False) == "period":
# https://github.com/pandas-dev/pandas/issues/24304
# convert ndarray[period] -> PeriodIndex
return PeriodIndex(values, freq=axis.freq).asi8
elif isinstance(values, (list, tuple, np.ndarray, Index)):
return [get_datevalue(x, axis.freq) for x in values]
return values


Expand Down Expand Up @@ -575,11 +587,18 @@ def _daily_finder(vmin, vmax, freq: BaseOffset) -> np.ndarray:
(vmin, vmax) = (int(vmin), int(vmax))
span = vmax - vmin + 1

dates_ = period_range(
start=Period(ordinal=vmin, freq=freq),
end=Period(ordinal=vmax, freq=freq),
freq=freq,
)
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore", "Period with BDay freq is deprecated", category=FutureWarning
)
warnings.filterwarnings(
"ignore", r"PeriodDtype\[B\] is deprecated", category=FutureWarning
)
dates_ = period_range(
start=Period(ordinal=vmin, freq=freq),
end=Period(ordinal=vmax, freq=freq),
freq=freq,
)

# Initialize the output
info = np.zeros(
Expand Down Expand Up @@ -1072,7 +1091,13 @@ def __call__(self, x, pos: int = 0) -> str:
fmt = self.formatdict.pop(x, "")
if isinstance(fmt, np.bytes_):
fmt = fmt.decode("utf-8")
period = Period(ordinal=int(x), freq=self.freq)
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
"Period with BDay freq is deprecated",
category=FutureWarning,
)
period = Period(ordinal=int(x), freq=self.freq)
assert isinstance(period, Period)
return period.strftime(fmt)

Expand Down
9 changes: 9 additions & 0 deletions pandas/tests/plotting/frame/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2487,6 +2487,15 @@ def test_secondary_y(self, secondary_y):
assert ax.get_ylim() == (0, 100)
assert ax.get_yticks()[0] == 99

@pytest.mark.slow
def test_plot_no_warning(self):
# GH 55138
# TODO(3.0): this can be removed once Period[B] deprecation is enforced
df = tm.makeTimeDataFrame()
with tm.assert_produces_warning(False):
_ = df.plot()
_ = df.T.plot()


def _generate_4_axes_via_gridspec():
import matplotlib.pyplot as plt
Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/plotting/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -973,3 +973,10 @@ def test_series_none_color(self):
ax = series.plot(color=None)
expected = _unpack_cycler(mpl.pyplot.rcParams)[:1]
_check_colors(ax.get_lines(), linecolors=expected)

@pytest.mark.slow
def test_plot_no_warning(self, ts):
# GH 55138
# TODO(3.0): this can be removed once Period[B] deprecation is enforced
with tm.assert_produces_warning(False):
_ = ts.plot()

0 comments on commit 6e6a683

Please sign in to comment.