I am trying to use pandas date_range
in the x-axis of a matplotlib.pyplot graph, while setting years to be the major ticks and months to be the minor ticks (for a timeline plot).
I came across a seemingly unexpected behaviour (noticed also as part of this SO question but unsolved), where the ticks are not aligned, and they are exhibiting an offset.
This code reproduces it for me (v3.5.2):
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.dates as mdates
x_range = pd.date_range('2015-01-01', '2021-06-01', freq='m')
y = np.linspace(1,1, len(x_range))
fig, ax = plt.subplots(figsize=(10, 1))
ax.plot(x_range, y)
loc = mdates.MonthLocator(interval=12)
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_minor_locator(AutoMinorLocator(12))
fmt = mdates.DateFormatter('%Y')
ax.xaxis.set_major_formatter(fmt)
Anyone dealt with this before? I suspect it has to do with months having 28, 30 and 31 days but could not investigate further.
You could do the following:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.dates as mdates
x_range = pd.date_range('2015-01-01', '2021-06-01', freq='A')
y = np.linspace(1, 1, len(x_range))
fig, ax = plt.subplots(figsize=(10, 1))
ax.plot(x_range, y)
loc = mdates.YearLocator()
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_minor_locator(mdates.MonthLocator())
fmt = mdates.DateFormatter('%Y')
ax.xaxis.set_major_formatter(fmt)
plt.show()