首页 文章

将绘图保存到图像文件,而不是使用Matplotlib显示它

提问于
浏览
825

我正在编写一个快速而肮脏的脚本来动态生成绘图 . 我使用下面的代码(来自Matplotlib文档)作为起点:

from pylab import figure, axes, pie, title, show

# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
title('Raining Hogs and Dogs', bbox={'facecolor': '0.8', 'pad': 5})

show()  # Actually, don't show, just save to foo.png

我不想在GUI上显示绘图,相反,我想将绘图保存到文件(例如foo.png),因此,例如,它可以在批处理脚本中使用 . 我怎么做?

15 回答

  • 993

    我使用了以下内容:

    import matplotlib.pyplot as plt
    
    p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
    p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
    plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)
    
    plt.savefig('data.png')  
    plt.show()  
    f.close()
    plt.close()
    

    我发现在保存图形后使用plt.show非常重要,否则它将无法工作 . figure exported in png

  • 0

    如果像我一样使用Spyder IDE,则必须禁用交互模式:

    plt.ioff()

    (此命令随科学启动自动启动)

    如果要再次启用它,请使用:

    plt.ion()

  • 132
    #write the code for the plot     
    plt.savefig("filename.png")
    

    该文件将保存在与运行的python / Jupyter文件相同的目录中

  • 69
    import datetime
    import numpy as np
    from matplotlib.backends.backend_pdf import PdfPages
    import matplotlib.pyplot as plt
    
    # Create the PdfPages object to which we will save the pages:
    # The with statement makes sure that the PdfPages object is closed properly at
    # the end of the block, even if an Exception occurs.
    with PdfPages('multipage_pdf.pdf') as pdf:
        plt.figure(figsize=(3, 3))
        plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
        plt.title('Page One')
        pdf.savefig()  # saves the current figure into a pdf page
        plt.close()
    
        plt.rc('text', usetex=True)
        plt.figure(figsize=(8, 6))
        x = np.arange(0, 5, 0.1)
        plt.plot(x, np.sin(x), 'b-')
        plt.title('Page Two')
        pdf.savefig()
        plt.close()
    
        plt.rc('text', usetex=False)
        fig = plt.figure(figsize=(4, 5))
        plt.plot(x, x*x, 'ko')
        plt.title('Page Three')
        pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
        plt.close()
    
        # We can also set the file's metadata via the PdfPages object:
        d = pdf.infodict()
        d['Title'] = 'Multipage PDF Example'
        d['Author'] = u'Jouni K. Sepp\xe4nen'
        d['Subject'] = 'How to create a multipage pdf file and set its metadata'
        d['Keywords'] = 'PdfPages multipage keywords author title subject'
        d['CreationDate'] = datetime.datetime(2009, 11, 13)
        d['ModDate'] = datetime.datetime.today()
    
  • 11

    解决方案 :

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib
    matplotlib.style.use('ggplot')
    ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
    ts = ts.cumsum()
    plt.figure()
    ts.plot()
    plt.savefig("foo.png", bbox_inches='tight')
    

    如果您确实要显示图像以及保存图像,请使用:

    %matplotlib inline
    

    import matplotlib 之后

  • 11

    如果您不喜欢“当前”图的概念,请执行以下操作:

    import matplotlib.image as mpimg
    
    img = mpimg.imread("src.png")
    mpimg.imsave("out.png", img)
    
  • 23

    解决方案是:

    pylab.savefig('foo.png')
    
  • 10

    正如其他人所说, plt.savefig()fig1.savefig() 确实是保存图像的方式 .

    但是我发现在某些情况下(例如Spyder有 plt.ion() :交互模式= On),总会显示数字 . 我通过强制关闭我的巨型循环中的数字窗口来解决这个问题,所以我在循环期间没有一百万个开放数字:

    import matplotlib.pyplot as plt
    fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
    ax.plot([0,1,2], [10,20,3])
    fig.savefig('path/to/save/image/to.png')   # save the figure to file
    plt.close(fig)    # close the figure
    
  • 17

    其他答案都是正确的 . 但是,我有时会发现我想稍后打开图形对象 . 例如,我可能想要更改标签大小,添加网格或进行其他处理 . 在一个完美的世界中,我只需重新运行生成绘图的代码,并调整设置 . 唉,世界并不完美 . 因此,除了保存为PDF或PNG之外,我还添加:

    with open('some_file.pkl', "wb") as fp:
        pickle.dump(fig, fp, protocol=4)
    

    像这样,我可以稍后加载图形对象并操纵设置 .

    我还为堆栈中的每个函数/方法写出了包含源代码和 locals() 字典的堆栈,以便稍后我可以准确地告诉生成该图的内容 .

    注意:要小心,因为有时这种方法会产生巨大的文件 .

  • 5

    根据问题Matplotlib (pyplot) savefig outputs blank image .

    有一点需要注意:如果您使用 plt.show 并且它应该在 plt.savefig 之后,或者您将给出一个空白图像 .

    一个详细的例子:

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    def draw_result(lst_iter, lst_loss, lst_acc, title):
        plt.plot(lst_iter, lst_loss, '-b', label='loss')
        plt.plot(lst_iter, lst_acc, '-r', label='accuracy')
    
        plt.xlabel("n iteration")
        plt.legend(loc='upper left')
        plt.title(title)
        plt.savefig(title+".png")  # should before plt.show method
    
        plt.show()
    
    
    def test_draw():
        lst_iter = range(100)
        lst_loss = [0.01 * i + 0.01 * i ** 2 for i in xrange(100)]
        # lst_loss = np.random.randn(1, 100).reshape((100, ))
        lst_acc = [0.01 * i - 0.01 * i ** 2 for i in xrange(100)]
        # lst_acc = np.random.randn(1, 100).reshape((100, ))
        draw_result(lst_iter, lst_loss, lst_acc, "sgd_method")
    
    
    if __name__ == '__main__':
        test_draw()
    
  • 140

    你可以这样做:

    plt.show(hold=False)
    plt.savefig('name.pdf')
    

    并且记得在关闭GUI图之前让savefig完成 . 这样您就可以预先看到图像 .

    或者,您可以使用 plt.show() 查看它然后关闭GUI并再次运行脚本,但这次将 plt.show() 替换为 plt.savefig() .

    或者,您可以使用

    fig, ax = plt.figure(nrows=1, ncols=1)
    plt.plot(...)
    plt.show()
    fig.savefig('out.pdf')
    
  • 40

    在使用plot()和其他函数创建所需内容之后,您可以使用这样的子句在绘制到屏幕或文件之间进行选择:

    import matplotlib.pyplot as plt
    
    fig = plt.figure(figuresize=4, 5)
    # use plot(), etc. to create your plot.
    
    # Pick one of the following lines to uncomment
    # save_file = None
    # save_file = os.path.join(your_directory, your_file_name)  
    
    if save_file:
        plt.savefig(save_file)
        plt.close(fig)
    else:
        plt.show()
    
  • 18

    刚刚在MatPlotLib文档中找到了这个链接,正好解决了这个问题:http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

    他们说阻止数字弹出的最简单方法是使用非交互式后端(例如Agg),通过 matplotib.use(<backend>) ,例如:

    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    plt.plot([1,2,3])
    plt.savefig('myfig')
    

    我个人更喜欢使用 plt.close( fig ) ,从那以后你可以选择隐藏某些数字(在循环期间),但仍然显示循环后数据处理的数字 . 它可能比选择非交互式后端要慢 - 如果有人测试过那么会很有趣 .

    UPDATE :对于Spyder,你通常不能以这种方式设置后端(因为Spyder通常会提前加载matplotlib,阻止你使用 matplotlib.use() ) .

    相反,使用 plt.switch_backend('Agg') ,或关闭Spyder首选项中的“启用支持”并自行运行 matplotlib.use('Agg') 命令 .

    从这两个提示:onetwo

  • 4

    虽然问题已得到解答,但我想在使用savefig时添加一些有用的提示 . 文件格式可以由扩展名指定:

    savefig('foo.png')
    savefig('foo.pdf')
    

    将分别给出栅格化或矢量化输出,两者都可能有用 . 此外,你会发现 pylab 在图像周围留下了一个慷慨的,通常是不受欢迎的空白区域 . 删除它:

    savefig('foo.png', bbox_inches='tight')
    
  • 26
    import matplotlib.pyplot as plt
    plt.savefig("image.png")
    

    在Jupyter Notebook中,您必须删除plt.show()并将plt.savefig()与其余的plt-code一起包含在一次单元格中 . 图像仍将显示在笔记本中 .

相关问题