For fixed custom x-axis labels in Matplotlib, pair each label with its intended position using ax.set_xticks(positions, labels). The older ax.set_xticklabels(labels) method is discouraged in the Matplotlib 3.11.2 documentation because labels can become misaligned if tick positions change.
Set custom labels and positions together
For a final plot with a known set of categories, pass the tick positions and labels in the same call. This makes their pairing explicit:
As an Amazon Associate I earn from qualifying purchases.
import matplotlib.pyplot as plt
values = [12, 18, 9]
positions = [0, 1, 2]
labels = ["North", "Central", "South"]
fig, ax = plt.subplots()
ax.bar(positions, values)
ax.set_xticks(positions, labels)
ax.set_xlabel("Region")
fig.tight_layout()
plt.show()
set_xticks establishes the locations and, when labels are supplied, assigns the corresponding text. Matplotlib’s current stable 3.11.2 Axes API documents this approach; see Axes.set_xticks.
When you need to keep set_xticklabels
If you are updating existing code that calls set_xticklabels, set the tick positions first and provide exactly one label for each position:
#1 Best Overall
positions = [0, 1, 2]
labels = ["North", "Central", "South"]
ax.set_xticks(positions)
ax.set_xticklabels(labels)
Matplotlib’s 3.11.2 Axis.set_ticklabels API marks the method as discouraged because label assignment depends on tick positions. It applies labels through a FixedFormatter, which chooses text by tick index rather than by tick value. If the locator moves or replaces the ticks, the text may no longer describe the intended positions. A fixed formatter should be paired with a fixed locator, which is why setting the ticks first matters.
Choose fixed labels or a formatter
Use fixed positions and labels when the plot should show a deliberate set of categories. Fixed tick settings are appropriate for a specific finished plot, but they do not automatically adapt when a viewer interacts with the Axes or changes its limits.
If each label should be calculated from its tick value, use a formatter instead. For example, FuncFormatter receives a tick value and its position, then returns the text to display:
from matplotlib.ticker import FuncFormatter
ax.xaxis.set_major_formatter(
FuncFormatter(lambda x, pos: f"${x:,.0f}")
)
This rule remains connected to the values as the locator chooses ticks. For date axes or specialized scales, use the corresponding date- or scale-aware locator and formatter rather than a hard-coded list. Matplotlib’s ticker API describes the available formatter and locator families; its Axis ticks guide explains how they work together.
Rank #3
Fix common label problems
- Labels appear shifted or change after plotting: use
ax.set_xticks(positions, labels), or establish a fixed locator before callingset_xticklabels. - The label and position counts differ: make the sequences the same length, with one label for each tick location.
- Labels should describe numeric values, not category slots: use a value-aware formatter such as
FuncFormatterrather than a fixed list indexed by position. - Ticks should respond to pan, zoom, or changing limits: let an automatic locator choose tick locations and use a formatter to generate their labels.
- You only want to change tick appearance: prefer
set_tick_paramsfor tick styling. Keyword arguments toset_xticklabelsaffect current tick objects and may not persist when ticks are regenerated.
These recommendations reflect Matplotlib’s stable 3.11.2 documentation, reviewed on October 7, 2026.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




