diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index e489b6a5e8f30..c58b42b326c05 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -251,7 +251,14 @@ def use_dynamic_x(ax: Axes, index: Index) -> bool: return index[:1].is_normalized period = Period(index[0], freq_str) assert isinstance(period, Period) - return period.to_timestamp().tz_localize(index.tz) == index[0] + period_naive = period.to_timestamp() + if index.tz is not None: + # Compare naive local times directly + tz_naive = index[0].tz_localize(None) # Strips tz, keeps local time + return period_naive == tz_naive + else: + return period_naive == index[0] + return True diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 779e539b3afba..d32f3e120ef4d 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -1003,3 +1003,18 @@ def test_bar_line_plot(self): x_limits = ax.get_xlim() assert x_limits[0] <= bar_xticks[0].get_position()[0] assert x_limits[1] >= bar_xticks[-1].get_position()[0] + + def test_tseries_plot_dst_transition(self): + """ + Test that plotting tz-aware timeseries works during DST fall-back transition. + """ + # GH62936 + tind = date_range( + "2025-10-26T00:00:00Z", + "2025-10-26T03:00:00Z", + freq="5min", + tz="utc", + ).tz_convert("MET")[12:] + + myts = DataFrame({"a": 1}, index=tind) + _check_plot_works(myts.plot)