Exact figure size in matplotlib with title, axis labels


Question

Similar questions have been asked before, but all of my search results don't address my problem. Take the following example code:

from matplotlib.pyplot import *
fig = figure(1, figsize=(3.25, 3))
plot([0,1,5,2,9])
title('title')
xlabel('xAxis')
ylabel('yAxis')
fig.savefig('test.png',dpi=600)

The resulting figure is 2040x1890 pixels, or 3.4"x3.15", and the x-label is cut off. Looking at the PNG file in an image editor, it appears that the axes and tick labels fit the desired size. I've tried taking the difference from the output size and requested size and feeding that back in (3.25 - (3.4-3.25) = 3.10, but matplotlib seems to add an arbitrary buffer and it still doesn't come out to the desired size. How does one make an overall figure that is the desired size?

1
18
5/7/2015 2:50:27 PM

Accepted Answer

In agreement with the comment from David Robinson, the figure produced here is 3.25 by 3 inches as measured by photoshop, although the xlabel does show cut-off (mpl 1.1.0 in python 2.6 64-bit, win7)

A solution to overcome the problem is to manually adjust the margins with subplot_adjust:

from matplotlib.pyplot import *
fig = figure(1, figsize=(3.25, 3))
plot([0, 1, 5, 2, 9])
title('title')
xlabel('xAxis')
ylabel('yAxis')
subplots_adjust(bottom=0.14)   # <--
fig.savefig('test.png', dpi=600) 

The default value of these margins are set in the matploblibrc file and you can modify it there permanently. The default value for the bottom margin in my case was 0.10.

Either if your figure is of a wrong size or correct, as in my case, you can use subplot_adjust to provide enough space for the label. Then if needed, you can calculate the correction to get the actual picture or figure size you want as you already did.

The final view of the saved figure depends on the size of that figure. If you show() your figure and you save it from the matplotlib view frame you get the label cut-off in the image. But if you increase manually the size of the image you will see the label appearing and if you save it then it will also appear in the saved image. Lets say that is WYSIWYG. Your figure is of a very small size and this makes your label to get cut. So another approach is to make a bigger figure maybe with lower dpi to keep overall size. This also works:

from matplotlib.pyplot import *
fig = figure(1, figsize=(6.5, 6))   # <---
plot([0, 1, 5, 2, 9])
title('title')
xlabel('xAxis')
ylabel('yAxis')
fig.savefig('test.png', dpi=300)    # <---

In any case, I would consider this as a matplolib bug, as you could expect to have an uncut figure after plot and save.

10
1/8/2012 11:01:28 AM

matplotlib 1.1.1 has added figure.tight_layout() (doc) that will do this for you.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon