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

我需要采取的图像,并保存后,一些过程。当我显示图形时,它看起来很好,但保存图形后,在保存的图像周围有一些空白。我已经尝试了savefig方法的'tight'选项,也没有工作。代码:

  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()
258011 次浏览

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

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

你必须将参数bbox_inches作为一个字符串,也许这就是为什么它之前对你不起作用的原因。


可能的重复:

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

如何设置matplotlib图的边距?< / >

减少matplotlib plot的左右边距

我不能说我确切地知道为什么或如何我的解决方案”工作,但这是我必须做的,当我想要绘制一对夫妇机翼部分的轮廓—没有白边距—转换为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)

我已经尝试停用不同的部分,但这总是导致一个白色边缘的地方。您甚至可以修改它,以保持胖线附近的数字限制,以避免由于缺乏边距而被剃除。

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

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

这适用于我保存一个numpy数组绘制的imshow文件

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()

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

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)

在尝试了上面的答案都没有成功之后(还有很多其他的帖子),最终对我有用的是

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

我按照这个顺序做,效果很好。

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)

下面的函数包含了上面的johannes答案。我已经用多个轴的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')

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

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

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

然而,这可能不适用于修改图形的复杂图。如果是这样,请参考使用plt.subplots_adjust约翰内斯的回答

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

另外还有你需要的东西

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

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

import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)
这对我很管用 plt.savefig(save_path,bbox_inches='tight', pad_inches=0, transparent=True) < / p >

所以解决方案取决于你是否调整子图。如果你指定了plt。Subplots_adjust(上,下,右,左),你不希望使用kwargs的bbox_inch ='tight'与plt。Savefig,因为它自相矛盾地创建空白填充。它还允许您将图像保存为与输入图像相同的亮度(600x600输入图像保存为600x600像素输出图像)。

如果你不关心输出图像大小的一致性,你可以省略plt。Subplots_adjust属性,只需使用bbox_inch ='tight'和pad_inch =0 kwargs与plt.savefig。

此解决方案适用于matplotlib 3.0.1、3.0.3和3.2.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')

在Jupyter笔记本中,可以添加这一行:

%config InlineBackend.print_figure_kwargs = {'pad_inches':0}

下面是一个简单的例子

import matplotlib.pyplot as plt
import numpy as np


%config InlineBackend.print_figure_kwargs = {'pad_inches':0}


fig, ax = plt.subplots()
ax.axis("off")
ax.imshow(np.fromfunction(lambda i, j: np.sin(j), (15, 15)), cmap="YlGnBu")

enter image description here