0

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')) 
Dan Harrison
  • 127
  • 1
  • 7
  • This is a very similar [question](https://stackoverflow.com/questions/21423158/how-do-i-change-the-range-of-the-x-axis-with-datetimes-in-matplotlib). Using `mdates` is a good solution. – Rawson May 15 '22 at 17:20
  • @Rawson thanks! I gave that a go earlier, and have updated the question to include the results. Regardless of the interval given it just doesn't work the way I want to. If using set_major_locator(1) I'd expect there to a Year from 1968-2022, instead it just gives me two years spaced weirdly apart – Dan Harrison May 15 '22 at 18:07
  • `ax.xaxis.set_major_locator(mdates.YearLocator(5))`. See the docs https://matplotlib.org/stable/api/dates_api.html#matplotlib.dates.YearLocator – Riley May 15 '22 at 22:09

1 Answers1

0

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))
Dan Harrison
  • 127
  • 1
  • 7