Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exact figure size in matplotlib with title, axis labels

Tags:

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?

like image 277
swint144 Avatar asked Jan 08 '12 05:01

swint144


People also ask

How do I change the axis label size in Matplotlib?

If we want to change the font size of the axis labels, we can use the parameter “fontsize” and set it your desired number.


2 Answers

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.

like image 67
joaquin Avatar answered Sep 17 '22 19:09

joaquin


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

like image 31
tacaswell Avatar answered Sep 21 '22 19:09

tacaswell