148

I'm using Matplotlib to plot a histogram. Using tips from my previous question: Matplotlib - label each bin, I've more or less got the kinks worked out.

There's one final issue - previously - the x-axis label ("Time (in milliseconds)") was being rendered underneath the x-axis tickmarks (0.00, 0.04, 0.08, 0.12 etc.)

No padding - Axis label underneath figures

Using the advice from Joe Kingston (see question above), I tried using:

ax.tick_params(axis='x', pad=30)

However, this moves both the x-axis tickmarks (0.00, 0.04, 0.08, 0.12 etc.), as well as the x-axis label ("Time (in milliseconds)"):

30 Padding - Both Axis Label and Tick Marks have Moved

Is there any way to move only the x-axis label to underneath the three rows of figures?

NB: You may need to open the PNGs below directly - Right Click on the image, then View Image (in FF), or Open image in new tab (Chrome). The image resize done by SO has rendered them nigh unreadable

cottontail
  • 10,268
  • 18
  • 50
  • 51
victorhooi
  • 16,775
  • 22
  • 90
  • 113

3 Answers3

266

use labelpad parameter:

pl.xlabel("...", labelpad=20)

or set it after:

ax.xaxis.labelpad = 20
HYRY
  • 94,853
  • 25
  • 187
  • 187
14

If the variable ax.xaxis._autolabelpos = True, matplotlib sets the label position in function _update_label_position in axis.py according to (some excerpts):

    bboxes, bboxes2 = self._get_tick_bboxes(ticks_to_draw, renderer)
    bbox = mtransforms.Bbox.union(bboxes)
    bottom = bbox.y0
    x, y = self.label.get_position()
    self.label.set_position((x, bottom - self.labelpad * self.figure.dpi / 72.0))

You can set the label position independently of the ticks by using:

    ax.xaxis.set_label_coords(x0, y0)

that sets _autolabelpos to False or as mentioned above by changing the labelpad parameter.

Kel Solaar
  • 3,660
  • 1
  • 23
  • 29
Matthias123
  • 882
  • 9
  • 15
  • 1
    For posterity, matplotlib now has [`.set_label_coords`](https://matplotlib.org/stable/api/_as_gen/matplotlib.axis.Axis.set_label_coords.html) which gives a similar level of control – mostsquares Oct 19 '22 at 22:19
0

Instead of padding manually, try assigning vertical alignment (va=):

ax.set_xlabel("x label", va='top');

If you modify the label padding manually as in @HYRY's answer, sometimes when you save the figure the label is cropped off. To include the label, set bbox_inches='tight' when you call savefig(). For example:

plt.plot(range(10))
plt.xlabel("x label", labelpad=30);
plt.savefig('img.png', bbox_inches='tight');

With the OOP API, the same would be:

fig, ax = plt.subplots()
ax.plot(range(10))
ax.set_xlabel("x label", labelpad=30);
fig.savefig('img.png', bbox_inches='tight');
cottontail
  • 10,268
  • 18
  • 50
  • 51