Matplotlib X-Axis Label Spacing and Removing Labels

If your department names are piled on top of each other, Matplotlib x axis label spacing comes down to three knobs: tick_params(pad=, labelrotation=) for the tick labels, labelpad for the axis title, and fewer labels when there’s no room.

You get stuck because Matplotlib never resizes anything for you: long names collide, and rotated ones run off the figure.

In this tutorial, I’ll fix a crowded sales chart three ways and then show the three clean ways to remove x-axis labels.

The sample sales chart with overlapping x-axis labels

Here’s the data: Q1 2026 sales in USD for eight departments at a made-up outdoor store, Rocky Trail Outfitters. I ran everything on Python 3.12.5 and Matplotlib 3.11.2.

import matplotlib.pyplot as plt

depts = ["Camping Gear", "Hiking Boots", "Climbing Equipment",
         "Water Sports", "Winter Apparel", "Bike Accessories",
         "Fishing Tackle", "Trail Nutrition"]
sales = [48250.75, 36410.20, 29875.40, 22140.95,
         41380.10, 18760.55, 15320.80, 9845.30]   # USD, Q1 2026

fig, ax = plt.subplots(figsize=(8, 4.5))
ax.bar(depts, sales, color="#2e7d5b")
ax.set_xlabel("Department")
ax.set_ylabel("Q1 2026 sales (USD)")
plt.show()
Matplotlib bar chart of Q1 2026 department sales where the default x-axis tick labels overlap each other
At the default size, the long department names run into each other.

If you’re still setting up the label itself, start with my Matplotlib x-axis label guide.

Method 1: Rotate and pad the tick labels with tick_params() (Recommended)

Same sales data, now with the names tilted 30 degrees and nudged away from the ticks:

import matplotlib.pyplot as plt

# depts and sales from the sample chart

fig, ax = plt.subplots(figsize=(8, 4.5))
ax.bar(depts, sales, color="#2e7d5b")
ax.tick_params(axis="x", labelrotation=30, pad=6)
plt.setp(ax.get_xticklabels(), ha="right", rotation_mode="anchor")
ax.set_xlabel("Department", labelpad=12)
ax.set_ylabel("Q1 2026 sales (USD)")
fig.tight_layout()
plt.show()
Matplotlib bar chart with x-axis department labels rotated 30 degrees, right aligned and padded so none overlap
The names sit at 30 degrees, end right under their bars, and nothing is clipped.

How does this code work?

labelrotation=30 tilts the names and pad=6 moves them 6 points below the tick marks (the default is 3.5). ha="right" with rotation_mode="anchor" pins each name’s end to its bar.

tight_layout() then grows the bottom margin, because rotated labels otherwise spill off the figure. For steeper angles, see rotating tick labels 45 and 90 degrees in Matplotlib.

Method 2: Move the axis title away with labelpad

labelpad controls the gap between the tick labels and the axis title, in points. Here’s how it measured on the same chart:

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

print("axes.labelpad  :", plt.rcParams["axes.labelpad"], "pt")
print("xtick.major.pad:", plt.rcParams["xtick.major.pad"], "pt")

fig, ax = plt.subplots(figsize=(8, 4.5))
ax.bar(["Camping Gear", "Hiking Boots"], [48250.75, 36410.20])

for pad in (4, 12, 24):
    ax.set_xlabel("Department", labelpad=pad)
    fig.canvas.draw()
    ticks = ax.get_xticklabels()[0].get_window_extent()
    title = ax.xaxis.label.get_window_extent()
    gap = ticks.y0 - title.y1
    print(f"labelpad={pad:>2} -> gap {gap:.1f} px at 100 dpi")

Output:

axes.labelpad  : 4.0 pt
xtick.major.pad: 3.5 pt
labelpad= 4 -> gap 5.6 px at 100 dpi
labelpad=12 -> gap 16.7 px at 100 dpi
labelpad=24 -> gap 33.3 px at 100 dpi
VS Code output of the Matplotlib axes.labelpad default and the measured pixel gap for labelpad 4, 12 and 24
The default is 4 points, and each larger labelpad widens the gap under the tick labels.

How does this code work?

The script measures the gap between the tick label box and the title box. At 100 dpi a point is about 1.39 pixels, so 12 points gives roughly 17 pixels.

Use it when a bigger or styled title crowds the names, like the ones in customizing the x-axis label color and size.

Method 3: Show every nth x-axis label

When even rotated names don’t fit, show fewer of them. Same sales data with eight bars, but keeping only every second label:

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

# depts and sales from the sample chart

def overlaps(ax):
    ax.figure.canvas.draw()
    boxes = [t.get_window_extent() for t in ax.get_xticklabels()
             if t.get_text()]
    return sum(a.overlaps(b) for a, b in zip(boxes, boxes[1:]))

fig, ax = plt.subplots(figsize=(8, 4.5))
ax.bar(depts, sales)
print("default      :", overlaps(ax), "overlapping pairs")

ax.set_xticks(ax.get_xticks()[::2])          # keep every 2nd label
print("every 2nd    :", overlaps(ax), "overlapping pairs")
print([t.get_text() for t in ax.get_xticklabels()])

Output:

default      : 7 overlapping pairs
every 2nd    : 0 overlapping pairs
['Camping Gear', 'Climbing Equipment', 'Winter Apparel', 'Fishing Tackle']

How does this code work?

The helper compares each label’s box with its neighbor. All 7 neighbor pairs overlap at first; slicing the tick positions with [::2] leaves four names and zero overlaps.

Important: don’t use MaxNLocator on a text axis. On this chart MaxNLocator(4) put ticks at -2.5, 0, 2.5, 5, 7.5 and 10, so Climbing Equipment landed between two bars.

Keep MaxNLocator for numbers and dates. More slicing patterns are in setting Matplotlib xticks range and every nth tick.

How do you remove x-axis labels in Matplotlib?

“Labels” can mean the axis title, the tick names or both. Here’s each version side by side on the same sales data:

import matplotlib.pyplot as plt

# depts and sales from the sample chart

fig, axes = plt.subplots(1, 3, figsize=(12, 5), sharey=True)
for ax in axes:
    ax.bar(depts, sales, color="#2e7d5b")
    ax.tick_params(axis="x", labelrotation=90)
    ax.set_xlabel("Department")

axes[0].set_xlabel("")                       # 1. axis title gone
axes[0].set_title('set_xlabel("")')
axes[1].tick_params(axis="x", labelbottom=False)   # 2. names gone
axes[1].set_title("labelbottom=False")
axes[2].set_xticks([])                       # 3. ticks + names gone
axes[2].set_title("set_xticks([])")
fig.tight_layout()
plt.show()
Three Matplotlib bar charts removing the x-axis title, the tick labels with labelbottom False, and all ticks with set_xticks
Left keeps the names without a title, the middle keeps tick marks and the title, and the right keeps only the title.

How does this code work?

set_xlabel("") clears only the title. labelbottom=False hides the names but keeps ticks for alignment, and set_xticks([]) removes the ticks and names but leaves the title.

For both axes and the frame, see removing tick labels in Matplotlib and turning off axis labels.

Which x-axis label spacing method should you use?

ProblemFix
Tick names overlaptick_params(labelrotation=30)
Title too close to namesset_xlabel(..., labelpad=12)
Too many names to fitset_xticks(ax.get_xticks()[::2])
Labels cut offlayout="constrained" or tight_layout()

Things to Keep in Mind with x-axis label spacing

  • Labels cut off: the default bottom margin is 0.11 of the figure, so use layout="constrained" or fig.subplots_adjust(bottom=0.25); grids are in Matplotlib tight_layout with wspace and hspace.
  • labelpad set too early: a later set_xlabel() without it resets the gap to 4 points.
  • Wrong pad: labelpad moves the title; pad in tick_params() moves the names.

If you’re polishing tick labels, these fit well next:

Frequently asked questions

How do I increase the space between x-axis labels in Matplotlib?

Rotate them with ax.tick_params(axis="x", labelrotation=30), widen the figure, or show every nth label.

How do I add space between the x-axis label and the ticks?

Pass labelpad, for example ax.set_xlabel("Department", labelpad=12).

How do I move tick labels away from the axis?

Use ax.tick_params(axis="x", pad=8); the default is 3.5 points.

How do I hide x-axis labels but keep the ticks?

Use ax.tick_params(axis="x", labelbottom=False).

How do I remove only the x-axis title?

Call ax.set_xlabel("") or ax.set(xlabel=None).

Where is labelpad documented?

See Axes.set_xlabel() in the Matplotlib docs.