matplotlib
python
data visualization
axis labels
plot customization

Date ticks and rotation

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Date ticks in Matplotlib become unreadable quickly when the labels are dense or verbose. The usual solution is to control both the date locator and formatter, then rotate the labels so the axis remains readable without overlapping text.

Let Matplotlib Know the Axis Contains Dates

A good date axis starts with actual datetime objects rather than string labels. That lets Matplotlib choose sensible tick spacing and formatting.

python
1import matplotlib.pyplot as plt
2import matplotlib.dates as mdates
3from datetime import datetime, timedelta
4
5x = [datetime(2025, 1, 1) + timedelta(days=i) for i in range(10)]
6y = [3, 4, 5, 6, 5, 4, 7, 8, 7, 6]
7
8fig, ax = plt.subplots()
9ax.plot(x, y)
10plt.show()

If you pass plain strings instead, Matplotlib cannot use its date locators and formatters properly.

Use a Date Locator and Formatter Together

Tick rotation helps, but it is not the whole answer. First decide how often ticks should appear.

python
1import matplotlib.pyplot as plt
2import matplotlib.dates as mdates
3from datetime import datetime, timedelta
4
5x = [datetime(2025, 1, 1) + timedelta(days=i) for i in range(30)]
6y = list(range(30))
7
8fig, ax = plt.subplots()
9ax.plot(x, y)
10
11locator = mdates.AutoDateLocator()
12formatter = mdates.ConciseDateFormatter(locator)
13ax.xaxis.set_major_locator(locator)
14ax.xaxis.set_major_formatter(formatter)
15
16plt.show()

AutoDateLocator picks sensible intervals based on the visible date range, and ConciseDateFormatter reduces repeated date text so labels stay shorter.

Rotate the Labels for Readability

Once the locator and formatter are sensible, rotate the labels. The simplest built-in option is:

python
fig.autofmt_xdate()

A full example:

python
1import matplotlib.pyplot as plt
2import matplotlib.dates as mdates
3from datetime import datetime, timedelta
4
5x = [datetime(2025, 1, 1) + timedelta(days=i) for i in range(15)]
6y = [i * i for i in range(15)]
7
8fig, ax = plt.subplots()
9ax.plot(x, y)
10
11locator = mdates.AutoDateLocator()
12formatter = mdates.DateFormatter("%Y-%m-%d")
13ax.xaxis.set_major_locator(locator)
14ax.xaxis.set_major_formatter(formatter)
15
16fig.autofmt_xdate(rotation=45, ha="right")
17plt.show()

This rotates the labels and adjusts the subplot layout so they do not get clipped.

Manual Control When autofmt_xdate Is Not Enough

Sometimes you need more precise styling. In that case, change the tick label objects directly.

python
for label in ax.get_xticklabels():
    label.set_rotation(60)
    label.set_horizontalalignment("right")

This is useful in multi-axes figures where one-size-fits-all formatting does not look good.

You can also reduce clutter by spacing ticks more deliberately:

python
ax.xaxis.set_major_locator(mdates.DayLocator(interval=7))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %d"))

That is often better than rotating dozens of labels that should not exist in the first place.

Think About Scale Before Rotation

Rotation solves overlap, but it does not solve too many ticks. If you are plotting years of daily data, the better fix is usually fewer major ticks, not steeper rotation.

A practical order of operations is:

  1. use datetime values
  2. choose a sensible locator
  3. choose a concise formatter
  4. rotate only as much as needed
  5. adjust layout so labels are visible

That keeps the chart readable without turning the x-axis into a wall of text.

Common Pitfalls

  • Passing date strings instead of datetime objects makes Matplotlib treat the axis less intelligently.
  • Rotating labels without adjusting the locator still leaves too many ticks on the axis.
  • Forgetting layout adjustment can clip rotated labels even when the formatting is otherwise correct.
  • Using a verbose formatter such as full timestamps for dense data creates clutter that rotation alone cannot fix.
  • Manually setting labels while also using automatic date formatting can create inconsistent or misleading axes.

Summary

  • Use actual datetime values so Matplotlib can apply date-aware locators and formatters.
  • Control tick density before worrying about rotation.
  • 'AutoDateLocator plus ConciseDateFormatter is a strong default for readable date axes.'
  • Use fig.autofmt_xdate() or manual label rotation when overlap remains.
  • The cleanest date axis comes from combining locator, formatter, rotation, and layout, not from rotation alone.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design