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

时间:2012-08-07 01:02:58

标签: python matplotlib

我需要拍摄一张照片并在经过一段时间后保存。当我显示它时,图形看起来很好,但在保存图形后,我在保存的图像周围有一些空白区域。我为'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()

14 个答案:

答案 0 :(得分:137)

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

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

你必须将bbox_inches的参数作为一个字符串,或许这就是为什么它没有为你提前工作。


可能重复:

Matplotlib plots: removing axis, legends and white spaces

How to set the margins for a matplotlib figure?

Reduce left and right margins in matplotlib plot

答案 1 :(得分:96)

我不能说我确切地知道我的“解决方案”为什么或如何工作,但当我想将几个翼型部分的轮廓 - 没有白色边距 - 绘制成PDF文件时,我必须这样做。 (注意我在IPython笔记本中使用了matplotlib,并使用了-pylab标志。)

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

我试图停用此功能的不同部分,但这总会导致某处出现白色边缘。你甚至可以对其进行修改,使得靠近图形极限的脂肪线因缺少边缘而受到削弱。

答案 2 :(得分:11)

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

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

答案 3 :(得分:8)

我发现以下代码可以很好地完成这项工作。

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)

答案 4 :(得分:5)

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

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参数。由于不明原因,当我在savefig中包含bbox参数时,我的图形向右偏心向上偏移。

答案 5 :(得分:5)

以下功能合并了上面的johannes-s答案。我已经使用plt.figureplt.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')

答案 6 :(得分:1)

对于任何想要以像素而不是英寸为单位的人来说,这都行得通。

再加上您通常需要的

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)

enter image description here

答案 7 :(得分:1)

这对我有用 plt.savefig(save_path,bbox_inches='tight', pad_inches=0, transparent=True)

答案 8 :(得分:0)

我按照这个顺序进行操作,就像一个魅力。

  

plt.axis(“ off”)

     

fig = plt.imshow(图像阵列,插值='最近')

     

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)

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

因此解决方案取决于您是否调整子图。如果您指定 plt.subplots_adjust (top, bottom, right, left),您不想将 bbox_inches='tight' 的 kwargs 与 plt.savefig 一起使用,因为它自相矛盾地创建了空白填充。它还允许您将图像保存为与输入图像相同的亮度(600x600 输入图像保存为 600x600 像素输出图像)。

如果您不关心输出图像大小的一致性,您可以省略 plt.subplots_adjust 属性,只使用 bbox_inches='tight' 和 pad_inches=0 kwargs 和 plt.savefig。

此解决方案适用于 matplotlib 版本 3.0.1、3.0.3 和 3.2.1。当您有超过 1 个子图时它也适用(例如 plt.subplots(2,2,...).

def save_inp_as_output(_img, c_name, dpi=100):
    h, w, _ = _img.shape
    fig, axes = plt.subplots(figsize=(h/dpi, w/dpi))
    fig.subplots_adjust(top=1.0, bottom=0, right=1.0, left=0, hspace=0, wspace=0) 
    axes.imshow(_img)
    axes.axis('off')
    plt.savefig(c_name, dpi=dpi, format='jpeg') 

答案 12 :(得分:-2)

这适用于我将使用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()

答案 13 :(得分:-2)

如果要显示要保存的内容,我建议使用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')

不幸的是,该解决方案在右侧和顶部仍然留有少量空白。