250

我需要拍摄一张图片并在经过一些处理后保存。当我显示它时,这个图看起来很好,但是在保存图之后,我在保存的图像周围有一些空白。我已经尝试了方法'tight'选项savefig,也没有工作。编码:

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

  fig = plt.figure(1)
  img = mpimg.imread("image.jpg")
  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("image.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()
4

14 回答 14

283

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

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

你必须把参数bbox_inches作为一个字符串,也许这就是为什么它不能更早地为你工作。


可能的重复:

Matplotlib 绘图:删除轴、图例和空白

如何设置 matplotlib 图形的边距?

减少matplotlib图中的左右边距

于 2012-08-07T13:39:05.087 回答
262

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

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)

我试图停用它的不同部分,但这总是会导致某处出现白边。您甚至可以对此进行修改,以防止靠近图形边界的粗线因缺少边距而被剃掉。

于 2014-12-01T11:45:51.573 回答
31

在尝试上述答案但没有成功(以及大量其他堆栈帖子)之后,最终对我有用的只是

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 参数。

于 2018-11-15T00:19:13.247 回答
25

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

plt.savefig(filename, transparent = True, bbox_inches = 'tight', pad_inches = 0)
于 2017-09-11T15:05:23.683 回答
17

以下函数包含上面 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')
于 2018-11-28T09:23:50.637 回答
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)
于 2018-05-24T15:16:58.857 回答
8

我按照这个顺序,它就像一个魅力。

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)
于 2018-11-27T13:06:10.023 回答
7

最直接的方法是使用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')

但是,这对于修改图形的复杂绘图可能并不可取。如果是这种情况,请参阅Johannes S 的答案。plt.subplots_adjust

于 2019-08-14T15:59:01.620 回答
7

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

于 2020-07-24T15:20:36.720 回答
6

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

    import matplotlib.pyplot as plt
    arr = plt.imread(path)
    plt.imsave('test.png', arr)
于 2019-06-28T09:18:15.573 回答
4

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

加上通常你还需要

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)

在此处输入图像描述

于 2019-09-20T02:05:42.853 回答
1

因此解决方案取决于您是否调整子图。如果您指定 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') 
于 2020-12-27T19:06:34.547 回答
0

你可以试试这个。它解决了我的问题。

import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)
于 2020-07-17T15:59:59.747 回答
-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()
于 2018-05-02T01:52:57.027 回答