在matplotlib中删除已保存图像周围的空白


172

我需要拍摄图像并经过一些处理将其保存。显示该图形时,它看起来不错,但是保存该图形后,在保存的图像周围有一些空白。我尝试过方法的'tight'选项savefig,也没有用。代码:

  import matplotlib.image as mpimg
  import matplotlib.pyplot as plt

  fig = plt.figure(1)
  img = mpimg.imread(path)
  plt.imshow(img)
  ax=fig.add_subplot(1,1,1)

  extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
  plt.savefig('1.png', bbox_inches=extent)

  plt.axis('off') 
  plt.show()

我正在尝试通过在图上使用NetworkX绘制基本图形并将其保存。我意识到没有图就可以,但是当添加图时,保存的图像周围会有空白;

import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import networkx as nx

G = nx.Graph()
G.add_node(1)
G.add_node(2)
G.add_node(3)
G.add_edge(1,3)
G.add_edge(1,2)
pos = {1:[100,120], 2:[200,300], 3:[50,75]}

fig = plt.figure(1)
img = mpimg.imread("C:\\images\\1.jpg")
plt.imshow(img)
ax=fig.add_subplot(1,1,1)

nx.draw(G, pos=pos)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig('1.png', bbox_inches = extent)

plt.axis('off') 
plt.show()


对我真正起作用的是使用其他工具(例如pdfcrop)裁剪pdf。
toliveira

Answers:


169

我不能说我确切知道我的“解决方案”为什么起作用或如何起作用,但是当我想将几个翼型截面的轮廓(没有白色边距)绘制到PDF文件时,这就是我要做的。(请注意,我在带有-pylab标志的IPython笔记本中使用了matplotlib。)

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.savefig("filename.pdf", bbox_inches = 'tight',
    pad_inches = 0)

我尝试停用此功能的不同部分,但这总是在某处导致空白。您甚至可以对此进行修改,以防止由于缺乏边距而使图形附近的粗线被刮掉。


6
终于有事了,非常感谢!顺便说一句,在我的情况下,只set_major_locator需要使用两行。
弗洛里安·布鲁克

6
我花了最后一个小时尝试各种操作,无法摆脱1px的白色边框。这是唯一有效的方法,特别是pad_inches=0其他答案未提及的方法。
AnnanFay

1
set_major_locator对我来说很关键
kmac

16
pad_inches帮助过我。
迈尔斯·贝克

5
matplotlib.ticker.NullLocator()
Joop

200

您可以通过bbox_inches="tight"在中设置来删除空白填充savefig

plt.savefig("test.png",bbox_inches='tight')

您必须将参数bbox_inches作为字符串输入,也许这就是为什么它对您较早不起作用的原因。


可能重复:

Matplotlib图:删除轴,图例和空白

如何设置matplotlib图形的边距?

减少matplotlib图中的左右边距


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

30
那不是正确。使用该bbox_inches选项时,还有另一个默认值会留一些空间。如果您真的想摆脱一切,则还需要使用pad_inches=0.0。当然,这种紧密的填充经常会中断,例如指数...
Mike

5
要同时去除黑色边缘,您可能需要设置pad_inches=-0.1
lenhhoxung

10
这根本行不通,您仍然在图形周围留有空格。设置透明选项(如一些答案中所述)也没有任何帮助,空格仍然存在,只是透明的。
BjornW

1
@piperchester是一个很好的问题,但可能应该作为一个新问题一并提出,这样它才不会在评论中迷失方向。您应该将新问题与旧问题联系起来!
上钩

21

在尝试了上述答案但没有成功(以及许多其他堆栈文章)之后,最终对我有用的只是

plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
            hspace = 0, wspace = 0)
plt.margins(0,0)
plt.savefig("myfig.pdf")

重要的是,这不包括bbox或padding参数。


4
这应该是公认的答案。此外,您甚至无需致电set_axis_off。它不会影响已保存的图像,因为在subplots_adjust轴位于图形的范围之外之后,无论如何都不会绘制孔洞。但是,在Jupyter笔记本电脑中,您需要显式禁用该轴,因为内联后端会覆盖这些设置。
MaxPowers

20

我从Arvind Pereira(http://robotics.usc.edu/~ampereir/wordpress/?p=626)找到了一些东西,似乎对我有用:

plt.savefig(filename, transparent = True, bbox_inches = 'tight', pad_inches = 0)

7
transparent=True看起来好像没有问题,但是只会隐藏空白区域,图像尺寸不好。
Vlady Veselinov

感谢您的提及pad_inches!我希望我早已知道此选项!
ingomueller.net

1
这适用于大多数情节,但是这消除了我混淆矩阵的右边界。只需添加一个小的填充pad_inches=.25
YTZ

14

以下功能合并了上面的johannes-s答案。我有测试过plt.figure,并plt.subplots()与多个轴,它工作得很好。

def save(filepath, fig=None):
    '''Save the current image with no whitespace
    Example filepath: "myfig.png" or r"C:\myfig.pdf" 
    '''
    import matplotlib.pyplot as plt
    if not fig:
        fig = plt.gcf()

    plt.subplots_adjust(0,0,1,1,0,0)
    for ax in fig.axes:
        ax.axis('off')
        ax.margins(0,0)
        ax.xaxis.set_major_locator(plt.NullLocator())
        ax.yaxis.set_major_locator(plt.NullLocator())
    fig.savefig(filepath, pad_inches = 0, bbox_inches='tight')

像魅力一样工作。先前的答案是我导出中的一些必需命令。
凯文S

11

我发现以下代码非常适合这项工作。

fig = plt.figure(figsize=[6,6])
ax = fig.add_subplot(111)
ax.imshow(data)
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.set_frame_on(False)
plt.savefig('data.png', dpi=400, bbox_inches='tight',pad_inches=0)

2
通常,如果答案包括对代码意图的解释,以及为什么不引入其他代码就能解决问题的原因,则答案会更有帮助。
蒂姆·迪克曼

7

我遵循了这个顺序,它就像一个魅力。

plt.axis("off")
fig=plt.imshow(image array,interpolation='nearest')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('destination_path.pdf',
    bbox_inches='tight', pad_inches=0, format='pdf', dpi=1200)

1
实际上,我发现此答案易于使用。
sikisis

1
这个为我工作;接受的答案没有。

3

对于任何想以像素而不是英寸为单位的人,都可以使用。

加上平时您还需要

from matplotlib.transforms import Bbox

然后,您可以使用以下命令:

my_dpi = 100 # Good default - doesn't really matter

# Size of output in pixels
h = 224
w = 224

fig, ax = plt.subplots(1, figsize=(w/my_dpi, h/my_dpi), dpi=my_dpi)

ax.set_position([0, 0, 1, 1]) # Critical!

# Do some stuff
ax.imshow(img)
ax.imshow(heatmap) # 4-channel RGBA
ax.plot([50, 100, 150], [50, 100, 150], color="red")

ax.axis("off")

fig.savefig("saved_img.png",
            bbox_inches=Bbox([[0, 0], [w/my_dpi, h/my_dpi]]),
            dpi=my_dpi)

在此处输入图片说明


您不必指定DPI,你可以使用默认的一个fig.dpi替代
intsco

1

我发现一种更简单的方法是使用plt.imsave

    import matplotlib.pyplot as plt
    arr = plt.imread(path)
    plt.imsave('test.png', arr)

被低估的答案。在长时间寻找如何保留分辨率并使用删除空白时,这对我有帮助plt.savefig()
nihal111 '19

仅在要将数组(!)保存为图像的情况下才有效。这不允许保存任意数字。
MaxPowers

任意图像是什么意思?图像不是值数组吗?
Parth92 '19

0

您可以尝试一下。它解决了我的问题。

import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)

-1

如果要显示要保存的内容,我建议您使用plt.tight_layout转换,因为它在使用时不会进行不必要的裁剪,因此实际上更可取plt.savefig

import matplotlib as plt    
plt.plot([1,2,3], [1,2,3])
plt.tight_layout(pad=0)
plt.savefig('plot.png')

-4

这对我有用,将用imshow绘制的numpy数组保存到文件

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
plt.imshow(img) # your image here
plt.axis("off")
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
        hspace = 0, wspace = 0)
plt.savefig("example2.png", box_inches='tight', dpi=100)
plt.show()
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.