1

Problem: I am trying to make a very simple bar chart in Matplotlib of a Pandas DataFrame. The DateTime index is causing confusion, however: Matplotlib does not appear to understand the Pandas DateTime, and is labeling the years incorrectly. How can I fix this?

Code

# Make date time series
index_dates = pd.date_range('2018-01-01', '2021-01-01')

# Make data frame with some random data, using the date time index
df = pd.DataFrame(index=index_dates,
                  data = np.random.rand(len(index_dates)), 
                  columns=['Data'])

# Make a bar chart in marplot lib
fig, ax = plt.subplots(figsize=(12,8))

df.plot.bar(ax=ax)

ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))

Instead of showing up as 2018-2021, however, the years show up as 1970 - 1973. enter image description here

I've already looked at the answers here, here, and documentation here. I know the date timeindex is in fact a datetime index because when I call df.info() it shows it as a datetime index, and when I call index_dates[0].year it returns 2018. How can I fix this? Thank you!

1
  • 1
    df.plot.bar only plots against range index and rename the tick labels. Commented Mar 17, 2021 at 20:19

1 Answer 1

1

The problem is with mixing df.plot.bar and matplotlib here.

df.plot.bar sets tick locations starting from 0 (and assigns labels), while matplotlib.dates expects the locations to be the number of days since 1970-01-01 (more info here).

If you do it with matplotlib directly, it shows labels correctly:

# Make a bar chart in marplot lib
fig, ax = plt.subplots(figsize=(12,8))

plt.bar(x=df.index, height=df['Data'])

ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))

Output:

chart

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer, this worked great! Changed from plt.bar() to ax.bar() to keep track of axis object more carefully.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.