1

The code below generates a plot with a properly-labeled x axis. But I don't want the full YYYY-MM-DD HH:MM:SS date format. No problem, a bunch of googling finally turned up the locator / formatter utilities. But if I uncomment the last line with the set_major_formatter, with no other changes, it formats the date as requested -- but now the x axis starts at the epoch (1970-01-01). !??

Image of the result

import pandas as pd 
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter

dates = pd.date_range(start="2021-01-01", end="2022-12-01")
data = [d.day for d in dates]
df = pd.DataFrame(index=dates, columns=[ "Data" ], data=data)
df.plot(kind="bar")
ax = plt.gca()
ax.xaxis.set_major_locator(mdates.MonthLocator(bymonth=(1, 4, 7, 10)))
ax.xaxis.set_minor_locator(mdates.MonthLocator())
date_form = DateFormatter("%Y-%m")
# ax.xaxis.set_major_formatter(date_form)
Derek O
  • 16,770
  • 4
  • 24
  • 43
garyfritz
  • 13
  • 5
  • based on the discussion in [this question](https://stackoverflow.com/questions/64919511/dateformatter-is-bringing-1970-as-year-not-the-original-year-in-the-dataset), this could be the result of using an outdated version of `pandas` and/or `matplotlib`. what versions or those two libraries are you using? – Derek O Dec 28 '22 at 00:04
  • 1
    Good thought, but no. pandas is 1.5.1, so not the latest (1.5.2), but very recent. matplotlib is 3.6.2, the latest stable release. – garyfritz Dec 28 '22 at 02:23
  • `kind='bar'` is a categorical plot - it is not numerical, so using a numerical `DateFormatter` is just taking the integers 0:len(data) and formatting them. – Jody Klymak Dec 28 '22 at 02:54
  • One of the answers at that site used to_datetime to convert the "Data" column. But I'm not sure how to do that to the index. Besides, df.info() says my df is already a DatetimeIndex. If I print df.index.values immediately before the plot, it shows correct 2022 DatetimeIndex values -- but the tick labels still start in 1970. – garyfritz Dec 28 '22 at 02:55
  • Note this works just fine if you don't do a bar plot – Jody Klymak Dec 28 '22 at 02:55
  • @JodyKlymak I think you're onto something. It wasn't formatting 0:len(data), it was displaying the YYYY-MM-DD HH:MM:SS format. But perhaps those were just strings generated from the category's index value?? I changed it to `kind='line'` and it formatted the chart nicely without the `set_major_formatter()`. Presumably because it was seeing actual datetimes. And, crucially, I added the major formatter and it DID NOT start at 1970. I'll have to look into the categorical behavior of bar plot. Thanks! – garyfritz Dec 28 '22 at 03:01
  • The `DateFormatter` is using `0:len(n)` for the tick values. If you want a bar plot, but want the x axis to be numeric, use Matplotlib's `bar`, not pandas' plotting. – Jody Klymak Dec 28 '22 at 17:00

0 Answers0