如何删除轴,图例,和白色填充

我想将颜色映射应用于图像,并写入结果图像,而不使用轴、标签、标题或matplotlib自动添加的任何内容。以下是我所做的:

def make_image(inputname,outputname):
data = mpimg.imread(inputname)[:,:,0]
fig = plt.imshow(data)
fig.set_cmap('hot')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig(outputname)

它成功地删除了图形的轴,但保存的图形显示了一个白色填充,以及实际图像周围的框架。

我如何删除它们(至少是白色填充)?

813354 次浏览

我从matehat,这里中学到了这个技巧:

import matplotlib.pyplot as plt
import numpy as np


def make_image(data, outputname, size=(1, 1), dpi=80):
fig = plt.figure()
fig.set_size_inches(size)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
plt.set_cmap('hot')
ax.imshow(data, aspect='equal')
plt.savefig(outputname, dpi=dpi)


# data = mpimg.imread(inputname)[:,:,0]
data = np.arange(1,10).reshape((3, 3))


make_image(data, '/tmp/out.png')

收益率

enter image description here

axis('off')方法比分别更改每个轴和边界更简洁地解决了其中一个问题。然而,它仍然在边界上留下了空白。在savefig命令中添加bbox_inches='tight'几乎就可以实现了;你可以在下面的例子中看到,留下的空白要小得多,但仍然存在。

更新版本的matplotlib可能需要bbox_inches=0而不是字符串'tight'(通过@episodeyang和@kadrach)

from numpy import random
import matplotlib.pyplot as plt


data = random.random((5,5))
img = plt.imshow(data, interpolation='nearest')
img.set_cmap('hot')
plt.axis('off')
plt.savefig("test.png", bbox_inches='tight')

enter image description here

你也可以将图形的范围指定为bbox_inches参数。这将消除图形周围的白色填充。

def make_image(inputname,outputname):
data = mpimg.imread(inputname)[:,:,0]
fig = plt.imshow(data)
fig.set_cmap('hot')
ax = fig.gca()
ax.set_axis_off()
ax.autoscale(False)
extent = ax.get_window_extent().transformed(plt.gcf().dpi_scale_trans.inverted())
plt.savefig(outputname, bbox_inches=extent)

可能的最简单的解决方案:

我只是简单地结合了问题中描述的方法和hook回答的方法。

fig = plt.imshow(my_data)
plt.axis('off')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('pict.png', bbox_inches='tight', pad_inches = 0)

在这段代码之后,没有空白和帧。

No whitespaces,坐标轴或帧

还没有人提到imsave,这使得它成为一行程序:

import matplotlib.pyplot as plt
import numpy as np


data = np.arange(10000).reshape((100, 100))
plt.imsave("/tmp/foo.png", data, format="png", cmap="hot")

它直接存储图像,即不添加任何轴或边界/填充。

enter image description here

首先,对于某些图像格式(例如TIFF),你可以在标题中保存颜色映射,大多数查看器将显示你的数据与颜色映射。

为了保存实际的matplotlib图像,它可以用于向图像添加注释或其他数据,我使用了以下解决方案:

fig, ax = plt.subplots(figsize=inches)
ax.matshow(data)  # or you can use also imshow
# add annotations or anything else
# The code below essentially moves your plot so that the upper
# left hand corner coincides with the upper left hand corner
# of the artist
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
# now generate a Bbox instance that is the same size as your
# single axis size (this bbox will only encompass your figure)
bbox = matplotlib.transforms.Bbox(((0, 0), inches))
# now you can save only the part of the figure with data
fig.savefig(savename, bbox_inches=bbox, **kwargs)

我喜欢ubuntu的的答案,但它没有显式地显示如何设置非方形图像的大小开箱即用,所以我修改了它,以便于复制粘贴:

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


def save_image_fix_dpi(data, dpi=100):
shape=np.shape(data)[0:2][::-1]
size = [float(i)/dpi for i in shape]


fig = plt.figure()
fig.set_size_inches(size)
ax = plt.Axes(fig,[0,0,1,1])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(data)
fig.savefig('out.png', dpi=dpi)
plt.show()

保存无边框的图像很容易,无论你选择什么dpi,如果pixel_size/dpi=size被保留。

data = mpimg.imread('test.png')
save_image_fix_dpi(data, dpi=100)

enter image description here

然而,展示是令人毛骨悚然的。如果你选择小的dpi,你的图像大小可以比你的屏幕大,你在显示时得到边框。然而,这并不影响储蓄。

因此,对于

save_image_fix_dpi(data, dpi=20)
显示变成有边框(但保存工作): enter image description here < / p >

这将删除所有的填充和边框:

from matplotlib import pyplot as plt


fig = plt.figure()
fig.patch.set_visible(False)


ax = fig.add_subplot(111)


plt.axis('off')
plt.imshow(data)


extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig("../images/test.png", bbox_inches=extent)

点赞的答案不再适用。让它工作,你需要 手动添加一个设置为[0,0,1,1]的轴,或删除图下的补丁

import matplotlib.pyplot as plt


fig = plt.figure(figsize=(5, 5), dpi=20)
ax = plt.Axes(fig, [0., 0., 1., 1.])
fig.add_axes(ax)
plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')                                # same as: ax.set_axis_off()


plt.savefig("test.png")


或者,你也可以把贴片去掉。不需要添加子图来删除填充。这是从Vlady的回答如下简化的

fig = plt.figure(figsize=(5, 5))
fig.patch.set_visible(False)                   # turn off the patch


plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')


plt.savefig("test.png", cmap='hot')

这已在2019/06/19用3.0.3版本测试。图片见下图:

enter image description here

一个更简单的方法是使用pyplot.imsave。详细信息,见luator的答案如下

感谢大家的精彩回答……我也有同样的问题,想要绘制一个没有额外填充/空间等的图像,所以非常高兴能在这里找到每个人的想法。

除了没有填充的图像,我还希望能够轻松添加注释等,而不仅仅是一个简单的图像情节。

因此,我最终所做的是将大卫的回答csnemes”结合起来,在图形创建时制作一个简单的包装器。当你使用它时,你不需要对imsave()或其他任何东西进行任何更改:

def get_img_figure(image, dpi):
"""
Create a matplotlib (figure,axes) for an image (numpy array) setup so that
a) axes will span the entire figure (when saved no whitespace)
b) when saved the figure will have the same x/y resolution as the array,
with the dpi value you pass in.


Arguments:
image -- numpy 2d array
dpi -- dpi value that the figure should use


Returns: (figure, ax) tuple from plt.subplots
"""


# get required figure size in inches (reversed row/column order)
inches = image.shape[1]/dpi, image.shape[0]/dpi


# make figure with that size and a single axes
fig, ax = plt.subplots(figsize=inches, dpi=dpi)


# move axes to span entire figure area
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)


return fig, ax

我发现这些都是有记录的……

https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.axis.html#matplotlib.axes.Axes.axis

我的代码…“bcK”是512x512的映像

plt.figure()
plt.imshow(bck)
plt.axis("off")   # turns off axes
plt.axis("tight")  # gets rid of white border
plt.axis("image")  # square up the image instead of filling the "figure" space
plt.show()

我一直在寻找几个代码来解决这个问题,这个问题的验证答案是唯一帮助我的代码。

这对于散点图和三坐标图很有用。你所要做的就是把边距改为零,这样就完成了。

plt.axis('off')

plt.savefig('example.png',bbox_inches='tight',pad_inches = 0)

让我得到无边界的图像。

这是最后对我有用的方法:

斧子。margin (x=0, y=0, tight=True)是关键行。

    fig = plt.figure(figsize=(8, 8))
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
ax.margins(x=0, y=0, tight=True)
fig.add_axes(ax)
for triangle in list_of_triangles:
x_points = [point[0] for point in triangle]
y_points = [point[1] for point in triangle]
plt.fill(x_points, y_points, 'k', edgecolor='k')
plt.savefig("test.png", bbox_inches=0, pad_inches=0)
plt.show()

这对我去除虱子很有效:

fig, axes = plt.subplots(2, figsize=(15, 20))


for ax in axes:
ax.get_xaxis().set_ticks([])
ax.get_yaxis().set_ticks([])

我试着

plt.rcParams['axes.spines.left'] = False
plt.rcParams['axes.spines.right'] = False
plt.rcParams['axes.spines.top'] = False
plt.rcParams['axes.spines.bottom'] = False
plt.rcParams['ytick.major.left'] = False
plt.rcParams['ytick.major.right'] = False
plt.rcParams['ytick.minor.left'] = False
plt.rcParams['ytick.minor.left'] = False
plt.rcParams['xtick.major.top'] = False
plt.rcParams['xtick.major.bottom'] = False
plt.rcParams['xtick.minor.top'] = False
plt.rcParams['xtick.minor.bottom'] = False
fig = plt.figure()

它删除了所有的边界和轴。

我从另一个关于Stack Overflow的问题中得到这个。