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

问题描述 投票:0回答:18

我想将颜色图应用于图像,并写入生成的图像,而不使用轴、标签、标题或 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)

它成功删除了图形的轴,但保存的图形在实际图像周围呈现白色填充和框架。

我怎样才能去除它们(至少是白色的填充物)?

python matplotlib
18个回答
642
投票

axis('off')
方法比单独更改每个轴和边框更简洁地解决了其中一个问题。然而,它仍然在边界周围留下了空白。将
bbox_inches='tight'
添加到
savefig
命令几乎就可以实现这一目标;您可以在下面的示例中看到,留下的空白空间小得多,但仍然存在。

较新版本的 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


196
投票

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


91
投票

可能最简单的解决方案:

我只是将问题中描述的方法和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)

此代码之后没有空格,也没有框架。

No whitespaces, axes or frame


50
投票

还没有人提到

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

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


20
投票
plt.axis('off')

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

让我获得无边框图像。


13
投票

我发现这一切都有记录......

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

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年6月19日使用版本

3.0.3
进行测试的。图片见下图:

更简单的方法是使用

pyplot.imsave
。详情请看下面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()

如果保留 Pixel_size/dpi=size,无论您选择什么 dpi,保存无边框图像都很容易。

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

但是显示效果很诡异。如果您选择较小的 dpi,则图像尺寸可能会大于屏幕,并且在显示过程中会出现边框。不过,这并不影响储蓄。

所以对于

save_image_fix_dpi(data, dpi=20)

显示出现边框(但保存有效):


3
投票
这最终对我有用:

ax.margins(x=0, y=0,ight=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()
    

3
投票
这有效:

plot.axis('off') ax = plot.gca() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False)
    

1
投票
首先,对于某些图像格式(即

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)
    

1
投票
感谢大家的精彩回答...我有完全相同的问题,只想绘制一个没有额外填充/空间等的图像,所以非常高兴在这里找到每个人的想法。

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

所以我最终做的就是将

David 的答案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
    

1
投票
这对我去除蜱有用:

fig, axes = plt.subplots(2, figsize=(15, 20)) for ax in axes: ax.get_xaxis().set_ticks([]) ax.get_yaxis().set_ticks([])
    

0
投票
我试过了

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 上的另一个问题得到这个。


0
投票
我更喜欢这个解决方案,我认为这是最干净的:

from numpy import random import matplotlib.pyplot as plt data = random.random((5,5)) fig,ax = plt.subplots() ax.imshow(data) ax.set_axis_off()
无需使用

plt

即可提供更多控制,并且只需要一行代码。

enter image description here


-1
投票
很惊讶这个没有出现。要绘制 N 个图像,您可以使用:

N = 5 data_array = np.random.rand(15,15,N) plt.figure(figsize=(5*N,5)) for i in np.arange(N): img = data_array[:,:,i] plt.subplot(1,N,i+1) plt.imshow(img) # Generate image plt.axis("off") # Remove axes plt.tight_layout() # Remove white space between images plt.show()
产生类似的东西

© www.soinside.com 2019 - 2024. All rights reserved.