Limits, ticks and tick formatting

Matplotlib · Practical · 12 min

Default ticks are often fine but wrong for percentages, currency or categories; precise control is what makes charts publication-ready.

Limits come from the data plus a small margin. Override them with ax.set_xlim(left, right) and ax.set_ylim(bottom, top); pass None for one side to keep it automatic. Reversing the order, set_ylim(10, 0), flips the axis. ax.margins(0) removes the padding.

Ticks are chosen by a locator and labelled by a formatter, both attached to each Axis (ax.xaxis, ax.yaxis).

Quick, explicit control:

ax.set_xticks([0, 5, 10], labels=["start", "middle", "end"])
ax.tick_params(axis="x", rotation=45, labelsize=8)

Rule-based control, which keeps working when data changes:

  • ticker.MultipleLocator(5): a tick every 5 units.
  • ticker.MaxNLocator(nbins=4, integer=True): at most a few integer ticks.
  • ticker.PercentFormatter(xmax=1): shows 0.25 as 25%.
  • ticker.StrMethodFormatter("{x:,.0f}"): thousands separators.
  • ticker.FuncFormatter(lambda v, pos: ...): anything you can compute.

Set them with ax.yaxis.set_major_locator(...) and ax.yaxis.set_major_formatter(...). Passing a format string directly, ax.yaxis.set_major_formatter("{x:.1f} s"), creates a StrMethodFormatter for you.

Minor ticks are off by default for linear axes; ax.minorticks_on() adds them. A light grid, ax.grid(True, alpha=0.3), helps readers look up values.

Hard-coded tick labels via set_xticks(labels=...) are tied to fixed positions. If the limits change later, they will no longer match; prefer a formatter when the labels are derived from values.

Example

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib import ticker

fig, ax = plt.subplots()
ax.plot([0, 1, 2, 3], [0.12, 0.35, 0.61, 0.9])
ax.set_xlim(0, 3)
ax.set_ylim(0, 1)
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1))
ax.grid(True, alpha=0.3)

fig.canvas.draw()                     # ticks are computed at draw time
print([t.get_text() for t in ax.get_yticklabels()][:3])  # ['0%', '20%', '40%']
fig.savefig("ticks.png")

Remember

  • set_xlim/set_ylim set ranges; reversed limits flip an axis
  • Locators choose tick positions, formatters choose their labels
  • Prefer formatters over hard-coded labels when labels derive from values

Watch out for

  • Setting fixed tick labels and then changing limits, leaving labels that no longer match positions.

Check yourself

  1. Your y values are fractions from 0 to 1 and you want labels like '40%'. What should you use?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: matplotlib.org/stable/users/explain/axes/axes_ticks.html