Skip to content

Commit f88403b

Browse files
committed
DEPR: secondary_y plotting with implicit resample
1 parent fdeeb05 commit f88403b

File tree

2 files changed

+52
-13
lines changed

2 files changed

+52
-13
lines changed

pandas/plotting/_matplotlib/timeseries.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
OFFSET_TO_PERIOD_FREQSTR,
2222
FreqGroup,
2323
)
24+
from pandas.errors import Pandas4Warning
25+
from pandas.util._exceptions import find_stack_level
2426

2527
from pandas.core.dtypes.generic import (
2628
ABCDatetimeIndex,
@@ -77,6 +79,13 @@ def maybe_resample(series: Series, ax: Axes, kwargs: dict[str, Any]):
7779
series = series.to_period(freq=freq)
7880

7981
if ax_freq is not None and freq != ax_freq:
82+
warnings.warn(
83+
"Plotting with mixed-frequency series is deprecated and "
84+
"will raise in a future version. Align series frequencies "
85+
"before plotting instead.",
86+
Pandas4Warning,
87+
stacklevel=find_stack_level(),
88+
)
8089
if is_superperiod(freq, ax_freq): # upsample input
8190
series = series.copy()
8291
# error: "Index" has no attribute "asfreq"

pandas/tests/plotting/test_datetimelike.py

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
BaseOffset,
1616
to_offset,
1717
)
18+
from pandas.errors import Pandas4Warning
1819

1920
from pandas.core.dtypes.dtypes import PeriodDtype
2021

@@ -627,7 +628,10 @@ def test_gap_upsample(self):
627628

628629
idxh = date_range(low.index[0], low.index[-1], freq="12h")
629630
s = Series(np.random.default_rng(2).standard_normal(len(idxh)), idxh)
630-
s.plot(secondary_y=True)
631+
632+
msg = "Plotting with mixed-frequency series is deprecated"
633+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
634+
s.plot(secondary_y=True)
631635
lines = ax.get_lines()
632636
assert len(lines) == 1
633637
assert len(ax.right_ax.get_lines()) == 1
@@ -820,7 +824,9 @@ def test_mixed_freq_hf_first(self):
820824
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
821825
_, ax = mpl.pyplot.subplots()
822826
high.plot(ax=ax)
823-
low.plot(ax=ax)
827+
msg = "Plotting with mixed-frequency series is deprecated"
828+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
829+
low.plot(ax=ax)
824830
for line in ax.get_lines():
825831
assert PeriodIndex(data=line.get_xdata()).freq == "D"
826832

@@ -833,7 +839,9 @@ def test_mixed_freq_alignment(self):
833839

834840
_, ax = mpl.pyplot.subplots()
835841
ax = ts.plot(ax=ax)
836-
ts2.plot(style="r", ax=ax)
842+
msg = "Plotting with mixed-frequency series is deprecated"
843+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
844+
ts2.plot(style="r", ax=ax)
837845

838846
assert ax.lines[0].get_xdata()[0] == ax.lines[1].get_xdata()[0]
839847

@@ -844,7 +852,9 @@ def test_mixed_freq_lf_first(self):
844852
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
845853
_, ax = mpl.pyplot.subplots()
846854
low.plot(legend=True, ax=ax)
847-
high.plot(legend=True, ax=ax)
855+
msg = "Plotting with mixed-frequency series is deprecated"
856+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
857+
high.plot(legend=True, ax=ax)
848858
for line in ax.get_lines():
849859
assert PeriodIndex(data=line.get_xdata()).freq == "D"
850860
leg = ax.get_legend()
@@ -858,7 +868,9 @@ def test_mixed_freq_lf_first_hourly(self):
858868
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
859869
_, ax = mpl.pyplot.subplots()
860870
low.plot(ax=ax)
861-
high.plot(ax=ax)
871+
msg = "Plotting with mixed-frequency series is deprecated"
872+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
873+
high.plot(ax=ax)
862874
for line in ax.get_lines():
863875
assert PeriodIndex(data=line.get_xdata()).freq == "min"
864876

@@ -951,7 +963,9 @@ def test_to_weekly_resampling(self):
951963
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
952964
_, ax = mpl.pyplot.subplots()
953965
high.plot(ax=ax)
954-
low.plot(ax=ax)
966+
msg = "Plotting with mixed-frequency series is deprecated"
967+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
968+
low.plot(ax=ax)
955969
for line in ax.get_lines():
956970
assert PeriodIndex(data=line.get_xdata()).freq == idxh.freq
957971

@@ -962,7 +976,9 @@ def test_from_weekly_resampling(self):
962976
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
963977
_, ax = mpl.pyplot.subplots()
964978
low.plot(ax=ax)
965-
high.plot(ax=ax)
979+
msg = "Plotting with mixed-frequency series is deprecated"
980+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
981+
high.plot(ax=ax)
966982

967983
expected_h = idxh.to_period().asi8.astype(np.float64)
968984
expected_l = np.array(
@@ -994,7 +1010,9 @@ def test_from_resampling_area_line_mixed(self, kind1, kind2):
9941010

9951011
_, ax = mpl.pyplot.subplots()
9961012
low.plot(kind=kind1, stacked=True, ax=ax)
997-
high.plot(kind=kind2, stacked=True, ax=ax)
1013+
msg = "Plotting with mixed-frequency series is deprecated"
1014+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1015+
high.plot(kind=kind2, stacked=True, ax=ax)
9981016

9991017
# check low dataframe result
10001018
expected_x = np.array(
@@ -1049,7 +1067,9 @@ def test_from_resampling_area_line_mixed_high_to_low(self, kind1, kind2):
10491067
)
10501068
_, ax = mpl.pyplot.subplots()
10511069
high.plot(kind=kind1, stacked=True, ax=ax)
1052-
low.plot(kind=kind2, stacked=True, ax=ax)
1070+
msg = "Plotting with mixed-frequency series is deprecated"
1071+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1072+
low.plot(kind=kind2, stacked=True, ax=ax)
10531073

10541074
# check high dataframe result
10551075
expected_x = idxh.to_period().asi8.astype(np.float64)
@@ -1096,7 +1116,9 @@ def test_mixed_freq_second_millisecond(self):
10961116
# high to low
10971117
_, ax = mpl.pyplot.subplots()
10981118
high.plot(ax=ax)
1099-
low.plot(ax=ax)
1119+
msg = "Plotting with mixed-frequency series is deprecated"
1120+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1121+
low.plot(ax=ax)
11001122
assert len(ax.get_lines()) == 2
11011123
for line in ax.get_lines():
11021124
assert PeriodIndex(data=line.get_xdata()).freq == "ms"
@@ -1110,7 +1132,9 @@ def test_mixed_freq_second_millisecond_low_to_high(self):
11101132
# low to high
11111133
_, ax = mpl.pyplot.subplots()
11121134
low.plot(ax=ax)
1113-
high.plot(ax=ax)
1135+
msg = "Plotting with mixed-frequency series is deprecated"
1136+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1137+
high.plot(ax=ax)
11141138
assert len(ax.get_lines()) == 2
11151139
for line in ax.get_lines():
11161140
assert PeriodIndex(data=line.get_xdata()).freq == "ms"
@@ -1247,7 +1271,9 @@ def test_secondary_upsample(self):
12471271
low = Series(np.random.default_rng(2).standard_normal(len(idxl)), idxl)
12481272
_, ax = mpl.pyplot.subplots()
12491273
low.plot(ax=ax)
1250-
ax = high.plot(secondary_y=True, ax=ax)
1274+
msg = "Plotting with mixed-frequency series is deprecated"
1275+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1276+
ax = high.plot(secondary_y=True, ax=ax)
12511277
for line in ax.get_lines():
12521278
assert PeriodIndex(line.get_xdata()).freq == "D"
12531279
assert hasattr(ax, "left_ax")
@@ -1482,7 +1508,11 @@ def test_secondary_y_mixed_freq_ts_xlim(self):
14821508
_, ax = mpl.pyplot.subplots()
14831509
ts.plot(ax=ax)
14841510
left_before, right_before = ax.get_xlim()
1485-
ts.resample("D").mean().plot(secondary_y=True, ax=ax)
1511+
1512+
rs = ts.resample("D").mean()
1513+
msg = "Plotting with mixed-frequency series is deprecated"
1514+
with tm.assert_produces_warning(Pandas4Warning, match=msg):
1515+
rs.plot(secondary_y=True, ax=ax)
14861516
left_after, right_after = ax.get_xlim()
14871517

14881518
# a downsample should not have changed either limit

0 commit comments

Comments
 (0)