matplotlib / matplotlib/matplotlib

[Bug]: ConciseDateFormatter doesn't handle DST changes correctly

Open
#29,160 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: date handling
Dominant language
Python
Stars
23.2k
Forks
8.5k
Avg merge
1d 6h
Merged PRs (30d)
66

Description

### Bug summary

When the time series to plot has a day light saving change and the time zone of data changes, the ticker labels formatted incorrectly. It seems to format time zone part instead of the correct base, in this example the day.

### Code for reproduction

```Python
import datetime

import matplotlib.pyplot as plt
import numpy as np

import matplotlib.dates as mdates
from zoneinfo import ZoneInfo

base = datetime.datetime(2005, 2, 1)
dates = [base + datetime.timedelta(hours=(2 * i)) for i in range(732)]
N = len(dates)
np.random.seed(19680801)
y = np.cumsum(np.random.randn(N))

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
lims = [(np.datetime64('2024-10-27'), np.datetime64('2024-11-10')),
(np.datetime64('2024-11-11'), np.datetime64('2024-11-22')),
(np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))
]

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))

for nn, ax in enumerate(axs):
# locator = mdates.AutoDateLocator()
locator = mdates.AutoDateLocator(tz=ZoneInfo("America/Los_Angeles"))
formatter = mdates.ConciseDateFormatter(locator)
formatter.formats = ['%y', # ticks are mostly years
'%b', # ticks are mostly months
'%d', # ticks are mostly days
'%H:%M', # hrs
'%H:%M', # min
'%S.%f', ] # secs
# these are mostly just the level above...
formatter.zero_formats = [''] + formatter.formats[:-1]
# ...except for ticks that are mostly hours, then it is nice to have
# month-day:
formatter.zero_formats[3] = '%d-%b'

formatter.offset_formats = ['',
'%Y',
'%b %Y',
'%d %b %Y',
'%d %b %Y',
'%d %b %Y %H:%M', ]
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

ax.plot(dates, y)
ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')

plt.show()
```

### Actual outcome

Screenshot 2024-11-20 at 4 19 38 PM

### Expected outcome

2nd graph of the same image shows the expected tick labels in the graph.

### Additional information

_No response_

### Operating system

_No response_

### Matplotlib Version

3.9.2

### Matplotlib Backend

macosx

### Python version

Python 3.11.6

### Jupyter version

_No response_

### Installation

pip

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied Python reproduction with matplotlib.dates.AutoDateLocator and ConciseDateFormatter, focusing on the plots spanning the daylight-saving transition. Trace how ConciseDateFormatter selects date components and time-zone information for ticker labels. Done means the labels show the correct base date across DST changes while preserving the expected output in the other plots.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data-visualization
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.