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

Hom*_*lli 1060 python plot matplotlib

我正在编写一个快速而肮脏的脚本来动态生成绘图.我使用下面的代码(来自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
Run Code Online (Sandbox Code Playgroud)

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

Hoo*_*ked 1307

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

from matplotlib import pyplot as plt

plt.savefig('foo.png')
plt.savefig('foo.pdf')
Run Code Online (Sandbox Code Playgroud)

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

savefig('foo.png', bbox_inches='tight')
Run Code Online (Sandbox Code Playgroud)

  • @Asmageddon在`plt.savefig`中你可以改变dpi,看看答案中的链接.创建图形时可以控制尺寸,请参阅http://matplotlib.org/api/figure_api.html#matplotlib.figure中的`figsize`. (41认同)
  • 有人可以解释为什么在保存之前显示会导致保存的空白图像吗? (26认同)
  • @SilentCloud 调用 show() 清除绘图。您必须先保存它,但还有其他选择。 (19认同)
  • 是否可以更改结果图像的尺寸? (9认同)
  • @MoTSCHIGGE你可以调用`plt.ioff()`来禁用`matplotlib.pyplot`命令中的交互性. (5认同)
  • 对于 Jupyter Notebook,plt.plot(data) 和 plt.savefig('foo.png') 必须位于同一单元格中。如果没有,您将看到一个空白文件。 (5认同)
  • @STMohammed`foo.png` _is_路径。例如,您可以将其放在类似`savefig(“ mydir / foo.png”)`的目录中。 (4认同)
  • bbox_inches='tight' 就像一个魅力。你让我今天一整天都感觉很好 (3认同)

Dem*_*mis 185

正如其他人所说,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 window
Run Code Online (Sandbox Code Playgroud)

  • 你也可以设置`plt.ioff()#turn of interactive plotting mode`,但如果你的代码退出并出现错误,这可能会禁用你想要使用的行为. (8认同)
  • 请注意,名称 `ax`/`fig`/`plt` 是由变量名称组成的 - 您可以随意称呼它们。无论哪种方式,它们都包含对象。您可以在此处查看“subplots”返回的对象:https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.subplots.html,以及“pyplot”模块在此处:https://matplotlib .org/tutorials/introductory/pyplot.html 。 (3认同)
  • 您将在Jupyter笔记本电脑中看到相同的问题。`plt.close(fig)`解决了它 (2认同)

Luk*_*ski 156

解决方案是:

pylab.savefig('foo.png')
Run Code Online (Sandbox Code Playgroud)

  • pylab 未定义 (4认同)

Dem*_*mis 80

刚刚在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')
Run Code Online (Sandbox Code Playgroud)

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

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

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

从这两个提示:,


won*_*ice 44

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

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)
Run Code Online (Sandbox Code Playgroud)

  • @ wonder.mice将有助于展示如何在不使用当前图形的情况下创建图像. (4认同)
  • 这不只是将`src.png`复制到`out.png`吗? (2认同)
  • 这只是一个例子,它显示如果您有一个图像对象(`img`),那么您可以使用`.imsave()`方法将其保存到文件中。 (2认同)

ger*_*rit 27

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

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

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

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

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

  • @CiprianTomoiaga我从未从交互式Python shell(Jupyter或其他)生成生产图。我从脚本中绘制所有内容。 (3认同)

Mar*_* P. 27

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

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4, 5))       # size in inches
# 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()
Run Code Online (Sandbox Code Playgroud)


Vic*_*iet 25

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()
Run Code Online (Sandbox Code Playgroud)


Cri*_*ñoz 21

我使用了以下内容:

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()
Run Code Online (Sandbox Code Playgroud)

我发现在保存图形后使用plt.show非常重要,否则它将无法正常工作.图中导出的数字

  • 对不起,这是什么?绘制的图像文件?`f= plt.savefig('data.png')` (3认同)

Cov*_*ich 12

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

plt.ioff()

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

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

plt.ion()


小智 12

你可以这样做:

plt.show(hold=False)
plt.savefig('name.pdf')
Run Code Online (Sandbox Code Playgroud)

并且记得在关闭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')
Run Code Online (Sandbox Code Playgroud)

  • 出现了意外的关键字参数“ hold” (2认同)

Dur*_*tam 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')
Run Code Online (Sandbox Code Playgroud)

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

%matplotlib inline
Run Code Online (Sandbox Code Playgroud)

import matplotlib


小智 9

使用时matplotlib.pyplot,您必须首先保存您的绘图,然后使用以下 2 行将其关闭:

fig.savefig('plot.png') # save the plot, place the path you want to save the figure in quotation
plt.close(fig) # close the figure window
Run Code Online (Sandbox Code Playgroud)


Pun*_*rud 7

import matplotlib.pyplot as plt
plt.savefig("image.png")
Run Code Online (Sandbox Code Playgroud)

在 Jupyter Notebook 中,您必须删除plt.show()和添加plt.savefig(),以及一个单元格中的其余 plt 代码。该图像仍将显示在您的笔记本中。


Jay*_*llo 6

根据问题Matplotlib(pyplot)savefig输出空白图像.

有一点需要注意:如果您使用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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


r_e*_*r_e 6

除了上面的那些,我添加__file__了名称,以便图片和 Python 文件获得相同的名称。我还添加了一些参数以使其看起来更好:

# Saves a PNG file of the current graph to the folder and updates it every time
# (nameOfimage, dpi=(sizeOfimage),Keeps_Labels_From_Disappearing)
plt.savefig(__file__+".png",dpi=(250), bbox_inches='tight')
# Hard coded name: './test.png'
Run Code Online (Sandbox Code Playgroud)


小智 6

只是一个额外的说明,因为我还无法对帖子发表评论。

如果您正在使用或类似的内容,请确保在保存图像后plt.savefig('myfig')添加。plt.clf()这是因为 savefig 不会关闭绘图,如果您在没有 a 的情况下添加到绘图中,plt.clf()您将添加到前一个绘图中。

您可能不会注意到您的图是否相似,因为它将绘制在前一个图上,但如果您处于保存图形的循环中,图将慢慢变得庞大并使您的脚本非常慢。


小智 5

#write the code for the plot     
plt.savefig("filename.png")
Run Code Online (Sandbox Code Playgroud)

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


Ham*_*eza 5

鉴于今天(提出这个问题时不可用)很多人使用 Jupyter Notebook 作为 python 控制台,有一种非常简单的方法将绘图保存为.png,只需从 Jupyter Notebook 调用matplotlibpylab类,绘制“内联”图形' jupyter 单元格,然后将该图形/图像拖到本地目录。不要忘记 %matplotlib inline在第一行!


小智 5

好吧,我确实建议使用包装器来渲染或控制绘图。示例可以是 mpltex ( https://github.com/liuyxpp/mpltex ) 或 Prettyplotlib ( https://github.com/olgabot/prettyplotlib )。

import mpltex

@mpltex.acs_decorator
def myplot():
  plt.figure()
  plt.plot(x,y,'b-',lable='xxx')
  plt.tight_layout(pad=0.5)
  plt.savefig('xxxx')  # the figure format was controlled by the decorator, it can be either eps, or pdf or png....
  plt.close()
Run Code Online (Sandbox Code Playgroud)

我基本上经常使用这个装饰器在美国化学会、美国物理学会、美国光学学会、Elsivier等各种期刊上发表学术论文。

示例如下图(https://github.com/MarkMa1990/gradientDescent): 梯度下降的一个例子