How to format the timeseries axis of a matplotlib plot like a pandas plot

Question:

I’ve created following graph with pd.Series([1]*month_limits.size, month_limits).plot(ax=ax)
How do I recreate same x ticks labels with just matplotlib? I mean years and month not overriding each other
enter image description here

Best I got is having years and months at the same time, but years are overriding months

import datetime

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

month_limits = pd.date_range('2021-08', '2023-01', freq="1m",
                             normalize=True) + datetime.timedelta(days=1)
plt.plot(month_limits, [1]*month_limits.size)

l1 = mdates.YearLocator()
l2 = mdates.MonthLocator(interval=1)
ax.xaxis.set_major_locator(l1)
ax.xaxis.set_minor_locator(l2)
ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(l1))
ax.xaxis.set_minor_formatter(mdates.ConciseDateFormatter(l2))

enter image description here

Asked By: bottledmind

||

Answers:

  • Use set_minor_locator and set_minor_formatter for the month '%b'
  • Use set_major_locator and set_major_formatter for the month and year '%bn%Y'
    • mdates.YearLocator(month=1) where month is the month that shows the year.
  • Tested in python 3.11.2, matplotlib 3.7.1
month_limits = pd.date_range('2021-08', '2023-01', freq="1m", normalize=True) +  pd.Timedelta(days=1)

fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(month_limits, [1]*month_limits.size)

# set locators
ax.xaxis.set_minor_locator(mdates.MonthLocator(interval=2))
ax.xaxis.set_major_locator(mdates.YearLocator(month=1))
# set formatters
ax.xaxis.set_major_formatter(mdates.DateFormatter('%bn%Y'))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b'))

enter image description here

month_limits = pd.date_range('2021-08', '2023-01', freq="1m", normalize=True) + pd.Timedelta(days=1)

fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(month_limits, [1]*month_limits.size)

# set locators
ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonth=range(1, 13, 3)))
ax.xaxis.set_major_locator(mdates.YearLocator(month=1))
# set formatter
ax.xaxis.set_major_formatter(mdates.DateFormatter('%bn%Y'))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b'))

enter image description here

Answered By: Trenton McKinney