'How to change the frequency of dates displayed on matplotlib chart

what's the best way of adjusting the frequency/interval for the x-axis in a matplotlib chart?

For example, the bottom 3 subplots should have a yearly frequency of 5 years as opposed to the default 2 years.

The date field associated with these charts is given every month and is of the format "YYYY-MM-DD" i.e. [1970-01-01, 1970-02-01, .... 2022-01-01, 2022-02-01]

enter image description here

Here's my code:

plt.figure(figsize=(15, 10))

# Plot 1
ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=3)
df_england.plot(x="Date", y="Index", kind="line", ax=ax1, title="House Price Index for England between 1968-2022")
ax1.set_ylabel("House Price Index (England)")

ax1.legend().set_visible(False)

# Plot 2
ax2 = plt.subplot2grid((2, 3), (1, 0), colspan=1)
df_england[(df_england["Date"] >="1970-06-01") & (df_england["Date"] <="1990")].plot(x="Date", y="Index", kind="line", ax=ax2)
ax2.set_ylabel("House Price Index (England)")

ax2.legend().set_visible(False)

# Plot 3
ax3 = plt.subplot2grid((2, 3), (1, 1), colspan=1)
df_england[(df_england["Date"] >="1990-01") & (df_england["Date"] <="2009-01")].plot(x="Date", y="Index", kind="line", ax=ax3)
ax3.set_ylabel("House Price Index (England)")
ax3.legend().set_visible(False)

# Plot 4
ax4 = plt.subplot2grid((2, 3), (1, 2), colspan=1)
df_england[(df_england["Date"] >="2009-01") & (df_england["Date"] <="2022-01")].plot(x="Date", y="Index", kind="line", ax=ax4)
ax4.set_xlim(['2009-01-01', '2028-09-01'])
ax4.set_ylim(70,200)

ax4.set_ylabel("House Price Index (England)")
ax4.legend().set_visible(False)

plt.savefig('long_term_trend_hpi.png', dpi=1200)
plt.show()

I have also tried using mdates and set_major_formatter but I have clearly implemented it incorrectly:

# Plot 1
ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=3)
df_england.plot(x="Date", y="Index", kind="line", ax=ax1, title="House Price Index for England between 1968-2022")
ax1.set_ylabel("House Price Index (England)")

ax1.xaxis.set_major_locator(md.YearLocator(1))
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) 
ax1.legend().set_visible(False)

enter image description here

Same sort of thing for 5 year period enter image description here

ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=3)
df_england.plot(x="Date", y="Index", kind="line", ax=ax1, title="House Price Index for England between 1968-2022")
ax1.set_ylabel("House Price Index (England)")
print(ax1.xaxis.get_major_locator())
ax1.xaxis.set_major_locator(md.YearLocator(5))
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y'))

I've also tried using the MaxNLocator approach with set_major_formatter, but again, the tick labels seem to have a mind of their own: enter image description here

ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=3)
df_england.plot(x="Date", y="Index", kind="line", ax=ax1, title="House Price Index for England between 1968-2022")
ax1.set_ylabel("House Price Index (England)")
print(ax1.xaxis.get_major_locator())
ax1.xaxis.set_major_locator(plt.MaxNLocator(10))
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) 


Solution 1:[1]

Thanks to this post, I was able to diagnose the issue as one with Pandas and Matplotlib using different ways of plotting charts

By passing x_compat= True to my df.plot() line it resolves the issue and allows me to work with ax.xaxis.set_major_locator(mdates.YearLocator(5))

ax1 = plt.subplot2grid((2, 3), (0, 0), colspan=3)
df_england.plot(x="Date", y="Index", kind="line", ax=ax1, title="House Price Index for England between 1968-2022", x_compat=True)
ax1.set_ylabel("House Price Index (England)")
ax1.xaxis.set_major_locator(mdates.YearLocator(5))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dan Harrison