问题描述:

I am producing a publication-quality plot to be embedded in latex and I would like to be very precise in terms of sizes and fonts (so that fonts are of the same size in the article as in the plot). To prevent the plot from scaling in latex I would like to have it exact size, but I cannot. Here is my code:

import matplotlib.pyplot as plt

from matplotlib import rc, rcParams

from numpy import sin

rc('text', usetex=True)

rc('font', family='serif', serif='Computer Modern Roman', size=8)

rc('legend', fontsize=10)

width_in = 5

fig = plt.figure(1, figsize=(width_in, 2))

ax = fig.add_subplot(111)

ax.plot(range(0,100), sin(range(0,100)))

fig.tight_layout()

fig.savefig('test.eps', bbox_inches='tight', pad_inches=0)

plt.close()

The problem is with bbox_inches='tight' and pad_inches=0. Adding those options makes my plot 4.76 inches wide instead of declared 5 inches. But I want them to save space. So how to solve it?

Edit: Well, the answers suggest to remove bbox_inches='tight' and pad_inches=0 and use just the tight_layout(). Then the images is of right size, however it has still some white padding around. I can remove it with fig.tight_layout(pad=0), but then the figure title it moved inside the box, which looks ugly. On the other hand I can use tight_layout(rect=[...]) and obtain the desired result, but it is a manual work to get the numbers right - I don't like it. Thus, currently I don't see any easy and general solution to my problem.

网友答案:

The problem you are having is that bbox_inches='tight' just removes all of the extra white space around your figure, it does not actually re-arrange anything in your figure, after it has been rendered.

You might need to tweak the parameters you pass to tight_layout (tutorial) to get your desired effect.

Hopefully this gets you pointed in the right direction.

网友答案:

Your original plot must have whitespace around it, otherwise bbox_inches=tight would not remove any of the area. There are two solutions to this that I know of:

  1. The simple method is to use tight_layout as mentioned by tcaswell.

  2. The more complicated, but more controllable method is to avoid using fig.add_subplot(111) and instead use fig.add_axes() which allows you to be much more strict in terms of how large your axes are when you define the axes instance. You can then tweak the size of your axes to take up as much of the figure area as required to maintain a 5" figure area. Once you have done this, I would recommend simply not using bbox_inches or set it to None (the default) to avoid unnessicary cropping. fig.add_axes() requires a rect parameter as its first argument which consists of [left_position, bottom_position, width, height] each of which range from 0 to 1.

Edit: After going through the tight_layout tutorial again, I have realized that it covers pretty much everything. I hadn't realized that it was able to maintain the aspect ratio of the axes instance easily, even if the aspect ratio of the figure is different from that of the axes instance. I tend to try to be very explicit when I define my axes areas because I deal with satellite imagery and try to keep it as the native sensor resolution or some factor of that sensor resolution, which requires a little bit more control.

相关阅读:
Top