From f0086d7afe62b6dd838bbbc2dd949b59bc782ebe Mon Sep 17 00:00:00 2001 From: Mohammed Date: Fri, 7 Nov 2025 00:21:55 +0530 Subject: [PATCH 1/3] Fix tz-aware comparison in plot() causing failures at DST boundary --- pandas/plotting/_matplotlib/timeseries.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index e489b6a5e8f30..5895499c98f76 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] + if index.tz is not None: + # Compare naive local times directly + period_naive = period.to_timestamp() + index_naive = index[0].tz_localize(None) # Strips tz, keeps local time + return period_naive == index_naive + else: + return period.to_timestamp() == index[0] + return True From 366c34138c388d47a2ba53be0bea0b0144c48466 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sat, 8 Nov 2025 19:43:29 +0530 Subject: [PATCH 2/3] add tests for dst transition plotting --- pandas/plotting/_matplotlib/timeseries.py | 8 ++++---- pandas/tests/plotting/test_series.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pandas/plotting/_matplotlib/timeseries.py b/pandas/plotting/_matplotlib/timeseries.py index 5895499c98f76..c58b42b326c05 100644 --- a/pandas/plotting/_matplotlib/timeseries.py +++ b/pandas/plotting/_matplotlib/timeseries.py @@ -251,13 +251,13 @@ def use_dynamic_x(ax: Axes, index: Index) -> bool: return index[:1].is_normalized period = Period(index[0], freq_str) assert isinstance(period, Period) + period_naive = period.to_timestamp() if index.tz is not None: # Compare naive local times directly - period_naive = period.to_timestamp() - index_naive = index[0].tz_localize(None) # Strips tz, keeps local time - return period_naive == index_naive + tz_naive = index[0].tz_localize(None) # Strips tz, keeps local time + return period_naive == tz_naive else: - return period.to_timestamp() == index[0] + 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..5b3471316bcb8 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -1003,3 +1003,19 @@ 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. + #62936 + """ + tind = pd.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) + From ecfafe07317179c50c45b1a5a02a7791b6f3c54a Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sat, 8 Nov 2025 19:58:21 +0530 Subject: [PATCH 3/3] fix pre commit issues --- pandas/tests/plotting/test_series.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 5b3471316bcb8..d32f3e120ef4d 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -1007,15 +1007,14 @@ def test_bar_line_plot(self): def test_tseries_plot_dst_transition(self): """ Test that plotting tz-aware timeseries works during DST fall-back transition. - #62936 """ - tind = pd.date_range( + # 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) -