Matplotlib绘图:删除轴,图例和空格

时间:2012-02-15 14:18:54

标签: python matplotlib

我是Python和Matplotlib的新手,我想简单地将色彩映射应用于图像并编写生成的图像,而不使用轴,标签,标题或通常由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)

它成功地移除了图形的轴,但保存的图形呈现白色填充和实际图像周围的框架。 如何删除它们(至少是白色填充)?感谢

14 个答案:

答案 0 :(得分:283)

我认为命令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

答案 1 :(得分:87)

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

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 :(得分:41)

可能最简单的解决方案:

我简单地将问题中描述的方法与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

答案 3 :(得分:22)

还没有人提及imsave,这使得它成为一个单行:

public class UserViewModel
{
    [Required(ErrorMessage = "The FirstName address is required")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "The LastName address is required")]
    public string LastName { get; set; }

    [Required(ErrorMessage = "The Email address is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    public string Email { get; set; }
}

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

enter image description here

答案 4 :(得分:8)

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

答案 5 :(得分:5)

这应该删除所有填充和边框:

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)

答案 6 :(得分:2)

我喜欢ubuntu's回答,但它没有明确显示如何设置开箱即用的非方形图像的大小,因此我修改了它以便于复制粘贴:

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)

enter image description here

然而,显示是怪异的。如果选择小dpi,则图像尺寸可能比屏幕大,并且在显示期间会出现边框。然而,这不会影响储蓄。

所以

save_image_fix_dpi(data, dpi=20)

显示屏有边框(但保存工作): enter image description here

答案 7 :(得分:2)

我发现所有文件都记录在案...

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

答案 8 :(得分: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)

答案 9 :(得分:1)

所有旧答案都不再起作用。您需要使用rejects才能使其正常工作。

<%@ LANGUAGE = "VBScript" %>

<%

        Dim string 
        string = "加賀屋 "  
        Set objStream = server.CreateObject("ADODB.Stream")
        objStream.Open
        objStream.CharSet = "UTF-8"
        Response.Write string
        objStream.WriteText(string) 
        objStream.SaveToFile Server.MapPath("/13/ama2019/TEST.html") , 2
        objStream.Close
        Set objStream = Nothing

%>

经过蜉雉螻・ 版的测试。

答案 10 :(得分:0)

已投票的答案不再起作用。要使其正常工作,您需要 手动添加设置为[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's answer below

开始简化
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。有关详细信息,see luator's answer bellow

答案 11 :(得分:0)

感谢大家的精彩回答...我遇到了同样的问题,只想绘制没有多余填充/空格等的图像,因此非常高兴在这里找到大家的想法。

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

因此,我最终要做的是在图形创建时将David's answercsnemes'结合在一起,制成一个简单的包装器。使用此功能时,以后不需要使用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

答案 12 :(得分:0)

我一直在寻找解决此问题的代码,对此question的经过验证的答案是唯一对我有帮助的代码。

这对于散点图和三点图很有用。您所要做的就是将边距更改为零,您就完成了。

答案 13 :(得分:0)

plt.axis('off')

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

给我无边的图像。