'How to show xticks for all 365 distinct tick labels on the X-axis using matplotlib?

I have plotted two line plots. For Y-axis as the number of values are less, the Y-axis is clearly visible. However, for X-axis there are 365 values corresponding to 365 days of the year. For X-axis, the X-axis values look utterly cluttered. I have created a list which corresponds to 'month-day'(starting from 01-01 till 12-31 i.e. 1st January till 31st December) and these are the xticks. I tried to rotate tick labels for X-axis both by 45 and 90 degrees. But it further clutters the X-axis tick labels.

I am using matplotlib for plotting line plots. Is there a way to show the X-axis tick labels clearly for all 365 values on the X-axis?
This is the output plot I got with rotation 90 for tick labels: enter image description here



Solution 1:[1]

The 365 tick marks cannot be clearly readable on one axis. I suggest using multiple x-axes to show data at different scales. This will give at least some information about what and when is happening.

# pip install matplotlib
# pip install pandas
# pip install numpy

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
import pandas as pd
import random
from datetime import date

# set test data
start_date = date(2022, 1, 1)
end_date = date(2022, 12, 31)
x1 = np.random.uniform(low=20, high=40, size=(365)).astype(int)
x2 = np.random.uniform(low=-40, high=-20, size=(365)).astype(int)
labels = [date.fromordinal(i) for i in range(start_date.toordinal(), end_date.toordinal()+1)]
df = pd.DataFrame({'labels': labels, 'chart1': x1, 'chart2': x2})

# plot charts
fig, ax1 = plt.subplots(figsize=(20,5))
ax1.plot(df['labels'], df['chart1'], 'r')
ax1.plot(df['labels'], df['chart2'], 'b')
plt.fill_between(labels, x1, x2, alpha=0.10, color='b', interpolate=True)

# set 1st x-axis (DAYS) with interval in 4 days to make xticks values visible
ax1.xaxis.set_major_locator(mdates.DayLocator(interval=4))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d'))
plt.xticks(rotation = 90)

# create a twin Axes sharing the yaxis
ax2, ax3, ax4 = ax1.twiny(), ax1.twiny(), ax1.twiny()

# Set 2nd x-axis (WEEK NUM)
ax2.xaxis.set_major_locator(mdates.WeekdayLocator())
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%U'))
ax2.xaxis.set_ticks_position('bottom')
ax2.xaxis.set_label_position('bottom')
ax2.spines['bottom'].set_position(('outward', 50))
ax2.set_xlim(ax.get_xlim())


# Set 3rd x-axis (MONTH)
ax3.xaxis.set_major_locator(mdates.MonthLocator())
ax3.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
ax3.xaxis.set_ticks_position('bottom')
ax3.xaxis.set_label_position('bottom')
ax3.spines['bottom'].set_position(('outward', 100))
ax3.set_xlim(ax.get_xlim())


# Set 4th x-axis (YEAR)
ax4.xaxis.set_major_locator(mdates.YearLocator())
ax4.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
ax4.xaxis.set_ticks_position('bottom')
ax4.xaxis.set_label_position('bottom')
ax4.spines['bottom'].set_position(('outward', 150))
ax4.set_xlim(ax.get_xlim())


# set labels for x-axes
ax1.set_xlabel('Day')
ax2.set_xlabel('Week num')
ax3.set_xlabel('Month')
ax4.set_xlabel('Year')

plt.show()

Returns

enter image description here

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 gremur