HOWTO · Matplotlib

How to Rotate X-Axis Tick Label Text in Matplotlib

Learn five ways to rotate Matplotlib x-axis tick labels and align them when long labels overlap.

On this page

To rotate x-axis tick labels in Matplotlib, pass an angle such as rotation=45 to plt.xticks, fig.autofmt_xdate, ax.set_xticklabels, plt.setp, or ax.tick_params. A 45-degree angle is a useful starting point when long horizontal labels overlap; align the rotated labels with ha="right" to keep their ends near their ticks. The examples below show when each API is useful.

Without rotation, category names such as month names sit horizontally and fill the whole axis width, so longer names or a narrower figure make neighbouring labels run together:

Line plot of monthly values with horizontal x-axis tick labels January, February, March, and April filling the axis width.

Rotate x-axis tick labels with plt.xticks

plt.xticks is a concise option when working with pyplot. Its rotation keyword sets the angle in degrees; the default is horizontal. This example plots categories and rotates their labels by 45 degrees.

import matplotlib.pyplot as plt

months = ["January", "February", "March", "April"]
values = [12, 18, 15, 22]

fig, ax = plt.subplots()
ax.plot(months, values, marker="o")
plt.xticks(rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

The same monthly line plot with x-axis tick labels rotated 45 degrees and right-aligned so each label ends at its tick.

Use plt.xticks for a quick change to the current axes. If your code already uses an Axes object, the corresponding methods below make the target axes explicit.

Rotate date-axis labels with fig.autofmt_xdate

For date-oriented plots, fig.autofmt_xdate formats the figure’s date labels and rotates them to improve readability. Its defaults also adjust alignment and the bottom margin; you can set rotation explicitly when you want a particular angle. Behavior depends on the figure’s axes and date format, so use it for date axes rather than as a general replacement for every tick-label setting.

import matplotlib.pyplot as plt
from datetime import date, timedelta

start = date(2024, 1, 1)
dates = [start + timedelta(days=7 * i) for i in range(6)]
values = [3, 5, 4, 7, 6, 9]

fig, ax = plt.subplots()
ax.plot(dates, values, marker="o")
fig.autofmt_xdate(rotation=45)
ax.grid(True)

Line plot over six weekly dates in January and February 2024 with the date labels rotated 45 degrees by autofmt_xdate.

This is convenient when the x-axis uses dates and their formatted labels need rotation and spacing. For ordinary categories, choose one of the tick-label methods in the other sections.

Set labels and rotation with ax.set_xticklabels

Use ax.set_xticklabels when you need to provide custom label text as well as its rotation. Set the tick positions explicitly first, and provide one label for each position so each string stays associated with the intended tick. Rotation alone does not require replacing the labels; use tick_params or plt.setp to keep the existing text.

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North region", "South region", "East region", "West region"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

Line plot with custom x-axis labels North region, South region, East region, and West region rotated 45 degrees and right-aligned.

Keep the positions and labels in the same order. If the plot’s ticks change later, update the custom labels to match them.

Set label properties with plt.setp

plt.setp updates properties on existing Matplotlib artists, including the current x-axis tick-label objects returned by ax.get_xticklabels(). It is useful when the labels are already in place and you only want to change their appearance.

import matplotlib.pyplot as plt

categories = ["First quarter", "Second quarter", "Third quarter", "Fourth quarter"]
values = [14, 17, 13, 21]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
plt.setp(ax.get_xticklabels(), rotation=45, ha="right")
ax.grid(True)
fig.tight_layout()

Line plot of quarterly values with the x-axis tick labels rotated 45 degrees and right-aligned using plt.setp.

Here, rotation changes the angle and ha sets horizontal alignment. This updates the current tick-label objects without replacing their text.

Set x-axis label rotation with ax.tick_params

ax.tick_params sets tick, tick-label, and grid-line properties for a chosen axis. Pass axis="x" and the lowercase labelrotation keyword to rotate x-axis labels while leaving their text and positions intact.

import matplotlib.pyplot as plt

categories = ["Planning", "Development", "Review", "Delivery"]
values = [2, 5, 3, 6]

fig, ax = plt.subplots()
ax.plot(categories, values, marker="o")
ax.tick_params(axis="x", labelrotation=45)
ax.grid(True)
fig.tight_layout()

Line plot of four project phases with the x-axis tick labels rotated 45 degrees using the tick_params labelrotation keyword.

Use this axis-level form when you already have an Axes reference. The keyword spelling is labelrotation, all lowercase.

Align rotated tick labels

Rotation changes the angle, while horizontal alignment controls which part of each label sits on its tick. With ha="right", the label’s right end meets the tick; with ha="left", its left end meets the tick; and with ha="center", its midpoint meets the tick. For 45-degree labels that extend to the left of their ticks, right alignment is a common choice. Try the options with your label lengths and chart layout.

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["January", "February", "March", "April"]
values = [4, 7, 5, 8]
alignments = ["right", "left", "center"]

fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, alignment in zip(axes, alignments):
    ax.plot(positions, values, marker="o")
    ax.set_xticks(positions)
    ax.set_xticklabels(labels, rotation=45, ha=alignment)
    ax.set_title(f'ha="{alignment}"')
    ax.grid(True)
fig.tight_layout()

Three side-by-side line plots comparing 45-degree x-axis labels with horizontal alignment right, left, and center.

Select alignment based on where you want each label to anchor. If labels still feel crowded, adjust the figure width or label wording in addition to rotating them.

Handle clipped labels and label-count errors

Two failures remain after the rotation itself works. First, ax.set_xticklabels replaces the label text, so the number of labels must equal the number of tick positions. Passing three labels for four positions fails before anything is drawn:

import matplotlib.pyplot as plt

positions = [0, 1, 2, 3]
labels = ["North", "South", "East"]
values = [8, 5, 9, 6]

fig, ax = plt.subplots()
ax.plot(positions, values, marker="o")
ax.set_xticks(positions)
ax.set_xticklabels(labels, rotation=45, ha="right")

The call ends with this error:

ValueError: The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the number of labels (3).

Add the missing label so the two sequences have the same length, in the same order. If you only need to rotate the existing text, prefer plt.setp or ax.tick_params instead: they keep the current labels, so this mismatch cannot occur.

Second, rotation changes the angle but does not create room below the axes. Render the set_xticklabels example above without its fig.tight_layout() call and the rotated labels run past the bottom edge of the figure — in a default-size render they extend about 31 pixels beyond the edge and are cut off mid-text:

Line plot with 45-degree region labels cut off at the bottom edge of the figure because tight_layout was not applied.

fig.tight_layout() recalculates the figure box so every label fits; measured the same way, the labels then end exactly at the figure edge with nothing outside it. fig.autofmt_xdate makes the same kind of margin adjustment for date axes. If labels still collide after the layout adjustment, shorten the label text or widen the figure rather than increasing the angle.