减少matplotlib图中的左右边距


178

我正在努力处理matplotlib中的地块边距。我使用下面的代码来生成图表:

plt.imshow(g)
c = plt.colorbar()
c.set_label("Number of Slabs")
plt.savefig("OutputToUse.png")

但是,我得到了一个在绘图的两边都有很多空白的输出图形。我已经搜索过Google并阅读了matplotlib文档,但似乎找不到如何减少这种情况的方法。


问题是由生成extent的,imshow图中的的空白量或生成的png中边界png的空白量savefig
unutbu

我认为两者都一样-视窗和PNG中似乎都有很多空间。但是,重要的输出是savefig- 产生的png文件,所以这就是我想要排序的内容。
robintw

之后,我刚刚将它们裁剪为GIMP。:/
endolith

Answers:


250

一种自动执行此操作的方法是使用bbox_inches='tight'kwarg plt.savefig

例如

import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')

另一种方法是使用 fig.tight_layout()

import matplotlib.pyplot as plt
import numpy as np

xs = np.linspace(0, 1, 20); ys = np.sin(xs)

fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)

# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')

5
有什么办法可以使它成为默认值?
endolith'7年

1
如果您有多个子图并且要保存每个子图,则也可以将其用于fig.savefig()。(plt.savefig()在这种情况下将不起作用。)
Abhranil Das 2013年

1
所有这些操作是在渲染图像后对其进行裁剪;如果您要强制执行特定的分辨率,则图像会变
熟练地

5
@detly-是的 这就是它的功能(尽管它也可以“裁剪”并扩大图像)。对于您想要的内容,请看一下fig.tight_layout()。最初编写此答案时,该功能不存在,否则我会更突出地提及它。
乔·肯顿

2
如果有人有问题,请使用fig = plt.gcf()
KyungHoon Kim

147

您可以使用subplots_adjust()函数调整matplotlib图形周围的间距:

import matplotlib.pyplot as plt
plt.plot(whatever)
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)

这将同时适用于屏幕上的图形并保存到文件中,并且即使在一个图形上没有多个图形,这也是调用的正确功能。

数字是图形尺寸的分数,需要进行调整以允许图形标签。


8
分配给参数的值(而不是更改量)是设置边距的位置。换句话说,如果你想10%带来的右缘缘,你应该设置正确= 0.9,不对= 0.1 matplotlib.sourceforge.net/api/...
drootang

1
需要指出的是,显然可以在plt.subplots_adjust()中指定负值。这样做甚至可以使您在图形区域之外绘制图形,也可以处理烦人的边距。
2013年

这也可以GridSpec通过调用update方法对对象起作用(请参阅stackoverflow.com/a/20058199/1030876)。
亚伦·沃埃尔克

57

所有你需要的是

plt.tight_layout()

在输出之前。

除了减少边距之外,这还将所有子图之间的空间紧密地分组:

x = [1,2,3]
y = [1,4,9]
import matplotlib.pyplot as plt
fig = plt.figure()
subplot1 = fig.add_subplot(121)
subplot1.plot(x,y)
subplot2 = fig.add_subplot(122)
subplot2.plot(y,x)
fig.tight_layout()
plt.show()

7
我认为这确实是最好的方法。它不需要像'bbox ='tight'这样保存图形,也可以解决狭窄图形中的所有其他布局问题。
dshepherd

2
这应该是正确的答案,因为它适用于图形而不是图像,其行为符合您的预期。
Majid alDosari

奇怪的是,与相比,它还改变了实际图的宽度(即,峰靠得更近)bbox_inches='tight',后者只是剪切边缘周围的白色空间,而使图独自留下。我用创建了该图plt.figure(figsize=(10,3))
弗里茨

9

只要使用ax = fig.add_axes([left, bottom, width, height]) ,如果你想图布局的精确控制。例如。

left = 0.05
bottom = 0.05
width = 0.9
height = 0.9
ax = fig.add_axes([left, bottom, width, height])

6

如果有人想知道在应用plt.tight_layout()或后如何去除其余的白色边距fig.tight_layout():使用参数pad1.08默认情况下),您可以使其更加紧密:“在图形边缘和子图,仅占字体大小的一部分。” 所以举个例子

plt.tight_layout(pad=0.05)

将其减少到很小的幅度。推杆0对我不起作用,因为它也会使子图的框被剪掉一点。


4
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)

1
“ pad_inches = -1”导致我的savefig只产生图的一部分。
Yu Shen

savefig函数中使用参数很优雅,但是pad_inches不一定在每种情况下都需要使用负值。
MichaelHuelsen

将其设置为0,有帮助
-Joop

4

matplotlibs subplots_adjust的问题在于,您输入的值相对于图形的x和y图大小。本示例是为了正确打印PDF的图形尺寸:

为此,我将相对间距重新计算为绝对值,如下所示:

pyplot.subplots_adjust(left = (5/25.4)/figure.xsize, bottom = (4/25.4)/figure.ysize, right = 1 - (1/25.4)/figure.xsize, top = 1 - (3/25.4)/figure.ysize)

以x维度表示“ figure.xsize”英寸,以y维度表示“ figure.ysize”英寸。因此,整个标签的左侧边距为5 mm,底部边距为4 mm,右侧边距为1 mm,顶部边距为3 mm。完成(x / 25.4)的转换是因为我需要将mm转换为英寸。

请注意,x的纯图表大小将为“ figure.xsize-左边距-右边距”,y的纯图表大小将为“ figure.ysize-底部边距-顶部边距”(以英寸为单位)

其他代码段(不确定这些代码段,我只想提供其他参数)

pyplot.figure(figsize = figureSize, dpi = None)

pyplot.savefig("outputname.eps", dpi = 100)

3
你从哪里得到xsizeysize从。我使用这些属性,然后得到AttributeError: 'Figure' object has no attribute 'xsize'
cj5

4

受以上萨米斯启发的答案:

margins = {  #     vvv margin in inches
    "left"   :     1.5 / figsize[0],
    "bottom" :     0.8 / figsize[1],
    "right"  : 1 - 0.3 / figsize[0],
    "top"    : 1 - 1   / figsize[1]
}
fig.subplots_adjust(**margins)

figsize是您在其中使用的元组 fig = pyplot.figure(figsize=...)


2

对我来说,以上答案matplotlib.__version__ = 1.4.3在Win7上不起作用。因此,如果我们只对图像本身感兴趣(即,如果我们不需要注释,轴,刻度,标题,ylabel等),那么最好将numpy数组另存为image而不是savefig

from pylab import *

ax = subplot(111)
ax.imshow(some_image_numpyarray)
imsave('test.tif', some_image_numpyarray)

# or, if the image came from tiff or png etc
RGBbuffer = ax.get_images()[0].get_array()
imsave('test.tif', RGBbuffer)

另外,使用opencv绘图功能(cv2.line,cv2.polylines),我们可以直接在numpy数组上绘制一些绘图。http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.