How to prevent Matplotlib from clipping away my axis labels?
Asked Answered
A

3

9

I'm preparing some plots for a scientific paper, which need to be wide and short in order to fit into the page limit. However, when I save them as pdf, the x axis labels are missing, because (I think) they're outside the bounding box.

Putting the following into an iPython notebook reproduces the problem.

%pylab inline
pylab.rcParams['figure.figsize'] = (8.0, 2.0)
plot([1,5,2,4,6,2,1])
xlabel("$x$")
ylabel("$y$")
savefig("test.pdf")

The resulting pdf file looks like this: enter image description here

How can I change the bounding box of the pdf file? Ideally I'd like a solution that "does it properly", i.e. automatically adjusts the size so that everything fits neatly, including getting rid of that unnecessary space to the left and right - but I'm in a hurry, so I'll settle for any way to change the bounding box, and I'll guess numbers until it looks right if I have to.

Antilebanon answered 2/4, 2014 at 10:39 Comment(0)
D
7

You can use plt.tight_layout() to have matplotlib adjust the layout of your plot. tight_layout() will automatically adjust the dimensions, and can also be used when you have (for example) overlapping labels/ticks/etc.

%pylab inline

pylab.rcParams['figure.figsize'] = (8.0, 2.0)

plot([1,5,2,4,6,2,1])

xlabel("$x$")
ylabel("$y$")

tight_layout()

savefig("test.pdf")

Here is a .png of the output (can't upload pdfs to SO but I've checked it and it works the same way for a pdf).

Example plot

Doc answered 2/4, 2014 at 10:49 Comment(1)
I'm accepting this, but any future visitors might also be interested in my own answer, which adjusts the bounding box to fit the plot, rather than the other way around.Antilebanon
A
15

After a spot of Googling, I found an answer: you can give bbox_inches='tight' to the savefig command and it will automatically adjust the bounding box to the size of the contents:

%pylab inline
pylab.rcParams['figure.figsize'] = (8.0, 2.0)
plot([1,5,2,4,6,2,1])
xlabel("$x$")
ylabel("$y$")
savefig("test.pdf",bbox_inches='tight')

enter image description here

Those are some tight inches, I guess.

Note that this is slightly different from Ffisegydd's answer, since it adjusts the bounding box to the plot, rather than changing the plot to fit the bounding box. (But both are fine for my purposes.)

Antilebanon answered 2/4, 2014 at 10:53 Comment(1)
For those that have a style sheet set up (I recommend this for everyone, see docs, it's a life-changer), you can set the savefig.bbox parameter to tight (instead of standard). To get the same result with plt.show() as plt.savefig() also set the figure.autolayout parameter to True (default is False).Sachs
D
7

You can use plt.tight_layout() to have matplotlib adjust the layout of your plot. tight_layout() will automatically adjust the dimensions, and can also be used when you have (for example) overlapping labels/ticks/etc.

%pylab inline

pylab.rcParams['figure.figsize'] = (8.0, 2.0)

plot([1,5,2,4,6,2,1])

xlabel("$x$")
ylabel("$y$")

tight_layout()

savefig("test.pdf")

Here is a .png of the output (can't upload pdfs to SO but I've checked it and it works the same way for a pdf).

Example plot

Doc answered 2/4, 2014 at 10:49 Comment(1)
I'm accepting this, but any future visitors might also be interested in my own answer, which adjusts the bounding box to fit the plot, rather than the other way around.Antilebanon
A
5

If you are preparing the plot for a scientific paper, I suggest to do the 'clipping' by yourself, using

plt.subplots_adjust(left,right,bottom,top,..)

after the creation of the figure and before saving it. If you are running from an ipython console you can also call subplots_adjust after the generation of the figure, and tune the margins by trial and error. Some backends (I think at least the Qt backend) also expose a GUI for this feature.

Doing this by hand takes time, but most times provides a more precise result, especially with Latex rendering in my experience.

This is the only option whenever you have to stack vertically or horizontally two figures (with a package like subfigure for example), as tight_layout will not guarantee the same margins in the two figures, and the axis will result misaligned in the paper.

This is a nice link on using matplotlib for publications, covering for example how to set the figure width to match the journal column width.

Achromic answered 2/4, 2014 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.