diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 177a38b526c6e..43e5e7adfcbf5 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -415,6 +415,7 @@ Period Plotting ^^^^^^^^ - Bug in :meth:`.DataFrameGroupBy.boxplot` failed when there were multiple groupings (:issue:`14701`) +- Bug in :meth:`DataFrame.plot` that causes a shift to the right when the frequency multiplier is greater than one. (:issue:`57587`) - Groupby/resample/rolling diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index d4587a6ccf90a..d438f521c0dbc 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -310,7 +310,7 @@ def maybe_convert_index(ax: Axes, data: NDFrameT) -> NDFrameT: if isinstance(data.index, ABCDatetimeIndex): data = data.tz_localize(None).to_period(freq=freq_str) elif isinstance(data.index, ABCPeriodIndex): - data.index = data.index.asfreq(freq=freq_str) + data.index = data.index.asfreq(freq=freq_str, how="start") return data diff --git a/pandas/tests/plotting/frame/test_frame.py b/pandas/tests/plotting/frame/test_frame.py index 25669ce75953f..65c9083d9fe2b 100644 --- a/pandas/tests/plotting/frame/test_frame.py +++ b/pandas/tests/plotting/frame/test_frame.py @@ -2578,6 +2578,21 @@ def test_plot_no_warning(self): _ = df.plot() _ = df.T.plot() + @pytest.mark.parametrize("freq", ["h", "7h", "60min", "120min", "3M"]) + def test_plot_period_index_makes_no_right_shift(self, freq): + # GH#57587 + idx = pd.period_range("01/01/2000", freq=freq, periods=4) + df = DataFrame( + np.array([0, 1, 0, 1]), + index=idx, + columns=["A"], + ) + expected = idx.values + + ax = df.plot() + result = ax.get_lines()[0].get_xdata() + assert all(str(result[i]) == str(expected[i]) for i in range(4)) + def _generate_4_axes_via_gridspec(): import matplotlib.pyplot as plt