如何去除坐标轴、图例和白色留白

486

我想将颜色映射应用到一张图片上,并将处理后的图片写入文件,但不希望使用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)

成功移除了图像的轴线,但是保存的图像周围有一个白色填充和边框。

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


2
这个问题的所有解决方案都集中在 imshow 上。如果您有一个散点图,下面的答案可能会对您有帮助:https://dev59.com/y5zha4cB1Zd3GeqPI7G0#40727744 - ImportanceOfBeingErnest
有关子情节,请参阅此问题 - undefined
18个回答

634

axis('off') 方法可以更简洁地解决一个问题,比分别更改每个轴和边框更方便。但它仍然会留下边界周围的空白。将 bbox_inches='tight' 添加到 savefig 命令中几乎可以解决这个问题;您可以在下面的示例中看到留下的空白区域更小了,但仍然存在。

更新版本的 matplotlib 可能需要使用整数 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')

在此输入图片描述


192

我从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


2
ax.set_axis_off() 是我在找的。 plt.axis('off') 会让我的整个图表变成空白。 - Antoine
这在使用matplotlib.figure.Figure而不是pyplot时有效,谢谢! - undefined

89

可能最简单的解决方案:

我只是简单地将问题描述中的方法和Hooked答案中的方法结合起来。

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)

运行该代码后,图像不会有任何空格、轴或者边框。

没有空格、轴或边框的图片


48

还没有人提到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")

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

在此输入图片描述


这个提示正是我正在寻找的!但我仍然很好奇到底存储了什么,即文件大小并不完全是100*100=10000字节。相反,它大约是983字节。有趣。 - Donna
1
@Donna 图像以PNG格式保存,该格式可以压缩数据。因此,生成的文件大小通常比仅计算像素时要小。 - luator

20
plt.axis('off')

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

使用上述代码可以得到无边框的图像。


13

12

这应该可以去除所有的填充和边框:

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)

9

您还可以通过指定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)

9

已点赞的答案不再适用。要使其正常工作,您需要手动添加一个轴,设置为 [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的回答:

查看下面luator的回答


6

我喜欢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相等,无论您选择何种DPI,都可以轻松地保存没有边框的图像。

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

在此输入图片描述

但是显示会有些问题。如果您选择小的dpi,您的图像大小可能会大于屏幕大小,在显示时会出现边框。然而,这不会影响保存。

因此,对于

save_image_fix_dpi(data, dpi=20)

显示屏变成有边框(但可以正常保存):图片描述

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接