0

I am plotting some time series data (cannot provide the data right now), but essentially I have two sets of daily data, over the same range of dates (16/10/2019 - 24/03/2022). I have created a figure consisting of two subplots adjacent to each other, one subplot for each data. Since they are both over the same range of dates, their x-axis is the same. As you can imagine, with daily data, there will be many dates (615) over the range I mentioned earlier. Therefore, I want to only display every 90th date on my plot. Here is the code I have used to acquire the plots:

# Create a figure with two subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Plot IT Results on first subplot
ax1.plot(it_test_returns.index, np.sqrt(it_forecast), label = 'ARCH(1)', color = 'red')
ax1.plot(it_test_returns.index, np.sqrt(it_garch_forecast), label = 'GARCH(1,1)', color = 'blue')
ax1.plot(it_test_returns.index, np.sqrt(it_egarch_forecast), label = 'EGARCH(1,1)', color = 'cyan')
ax1.plot(it_test_returns.index, it_actual_volatility, label = 'Actual Volatility', color = 'green', linewidth = 3)
locator1 = IndexLocator(base=90, offset=0)
formatter = mdates.DateFormatter('%d/%m/%Y')
ax1.xaxis.set_major_locator(locator1)
ax1.xaxis.set_major_formatter(formatter)
plt.xticks(rotation=45)
ax1.set_xlabel('Date')
ax1.set_ylabel('Volatility')
ax1.set_title('IT Sector Daily Volatility')
ax1.legend()

# Plot Utilities Results on second subplot
ax2.plot(util_test_returns.index, np.sqrt(util_forecast), label = 'ARCH(1)', color = 'red')
ax2.plot(util_test_returns.index, np.sqrt(util_garch_forecast), label = 'GARCH(1,1)', color = 'blue')
ax2.plot(util_test_returns.index, np.sqrt(util_egarch_forecast), label = 'EGARCH(1,1)', color = 'cyan')
ax2.plot(util_test_returns.index, util_actual_volatility, label = 'Actual Volatility', color = 'green', linewidth = 3)
locator2 = IndexLocator(base=90, offset=0)
formatter = mdates.DateFormatter('%d/%m/%Y')
ax2.xaxis.set_major_locator(locator2)
ax2.xaxis.set_major_formatter(formatter)
plt.xticks(rotation=45)
ax2.set_xlabel('Date')
ax2.set_ylabel('Volatility')
ax2.set_title('Utilities Sector Daily Volatility')
ax2.legend()

# Adjust spacing between subplots
fig.subplots_adjust(wspace=0.3)

# Display the figure
plt.tight_layout()
plt.savefig(r"C:\Users\Sidha\OneDrive\Documents\Year 3 BSc Project\vol_forecasts.png", dpi=600)
plt.show()

For some reason, the x-axis on the right subplot (ax2) displays the dates exactly how I want them, but the x-axis on the left subplot (ax1) seems to be trying to display all the dates, despite the fact the code is essentially the same (as far as I am aware) for ax1 and ax2. Here is an image of the axis to show what I mean: enter image description here

I have compared it_test_returns.index and 'util_test_returns.index` and they are exactly the same:

it_test_returns.index
Out[50]: 
DatetimeIndex(['2019-10-16', '2019-10-17', '2019-10-18', '2019-10-21',
               '2019-10-22', '2019-10-23', '2019-10-24', '2019-10-25',
               '2019-10-28', '2019-10-29',
               ...
               '2022-03-11', '2022-03-14', '2022-03-15', '2022-03-16',
               '2022-03-17', '2022-03-18', '2022-03-21', '2022-03-22',
               '2022-03-23', '2022-03-24'],
              dtype='datetime64[ns]', name='Date', length=615, freq=None)

util_test_returns.index
Out[51]: 
DatetimeIndex(['2019-10-16', '2019-10-17', '2019-10-18', '2019-10-21',
               '2019-10-22', '2019-10-23', '2019-10-24', '2019-10-25',
               '2019-10-28', '2019-10-29',
               ...
               '2022-03-11', '2022-03-14', '2022-03-15', '2022-03-16',
               '2022-03-17', '2022-03-18', '2022-03-21', '2022-03-22',
               '2022-03-23', '2022-03-24'],
              dtype='datetime64[ns]', name='Date', length=615, freq=None)

So I don't understand why I am getting this issue.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158

1 Answers1

1

It appears that the issue with the x-axis ticks on the left subplot (ax1) is caused by using plt.xticks(rotation=45) instead of applying the rotation specifically to each axis object. To fix this issue, you can apply the rotation to each axis individually as follows:

    # Modify x-axis ticks rotation for ax1
    for label in ax1.get_xticklabels():
        label.set_rotation(45)

    # Modify x-axis ticks rotation for ax2
    for label in ax2.get_xticklabels():
        label.set_rotation(45)

Replace the plt.xticks(rotation=45) line in your code with the above lines, and the x-axis ticks on both subplots should display correctly.

  • I think you can go simpler with `for ax in (ax1, ax2): ax.set_xticks(rotation=45)` ([`Axes.set_xticks()`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xticks.html)) – paime Apr 25 '23 at 03:10
  • My bad, it would be `ax.set_xticks(ax.get_xticks(), ax.get_xticklabels(), rotation=45)`, so not obviously simpler – paime Apr 25 '23 at 03:18