我需要拍摄图像并在经过一些处理后保存它。当我显示它时,该图看起来很好,但保存该图后,我在保存的图像周围有一些空白。我已经尝试过
'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()
您可以通过在
bbox_inches="tight"
中设置 savefig
来删除空白填充:
plt.savefig("test.png",bbox_inches='tight')
您必须将参数作为字符串放入
bbox_inches
,也许这就是它之前对您不起作用的原因。
可能的重复:
我不能声称我确切地知道我的“解决方案”的工作原理或原理,但这就是当我想将几个机翼剖面的轮廓(没有白边距)绘制到 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)
我尝试停用其中的不同部分,但这总是会导致某个地方出现白边。您甚至可以对此进行修改,以防止接近图形极限的脂肪线因缺乏边距而被剃掉。
在尝试了上述答案但没有成功(以及大量其他堆栈帖子)之后,最终对我有用的是
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 参数。
我从 Arvind Pereira (http://robotics.usc.edu/~ampereir/wordpress/?p=626) 找到了一些东西,似乎对我有用:
plt.savefig(filename, transparent = True, bbox_inches = 'tight', pad_inches = 0)
以下函数合并了上面 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')
这对我有用
plt.savefig(save_path,bbox_inches='tight', pad_inches=0, transparent=True)
最直接的方法是使用
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
。
我发现以下代码非常适合这项工作。
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.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)
我发现一个更简单的方法是使用
plt.imsave
:
import matplotlib.pyplot as plt
arr = plt.imread(path)
plt.imsave('test.png', arr)
对于任何想要以像素而不是英寸为单位工作的人来说,这都可以。
加上您通常还需要的
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)
所以解决办法取决于你是否调整子图。如果您指定 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')
在 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")
你可以试试这个。它解决了我的问题。
import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img, cmap=cmap)
我通常需要从 PDF 文件中裁剪空白以获取科学论文。调整 matplotlib 以真正删除所有空白从来没有完美地工作过,并且仍然存在一些空白...... 如果您使用 pdflatex,包含的 pdfcrop 可执行文件被证明对于从导出的图形中删除空格非常有用。因此,导出 PDF 后,pdfcrop 会删除剩余的空白。下面是一个使用 pdfcrop 自动裁剪保存的图形的 Python 代码片段。只需调用函数而不是 plt.savefig:
import subprocess
import os
def save_and_crop(path, *args, **kwargs):
filename, file_extension = os.path.splitext(path)
plt.savefig(path, *args, **kwargs)
if file_extension == ".pdf":
cropped_path = filename + "_cropped" + file_extension
subprocess.run(["pdfcrop", path, cropped_path], stdout=subprocess.DEVNULL)
这对我来说很有效,可以将用 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()