Save plot to image file instead of displaying it using Matplotlib
我正在写一个快速而肮脏的脚本来生成动态的绘图。我使用下面的代码(来自matplotlib文档)作为起点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
我不想在图形用户界面上显示绘图,相反,我想将绘图保存到一个文件(比如foo.png)中,以便它可以在批处理脚本中使用。我该怎么做?
当问题得到回答时,我想在使用matplotlib.pyplot.savefig时添加一些有用的提示。文件格式可以由扩展名指定:
1 2 3 4 | from matplotlib import pyplot as plt plt.savefig('foo.png') plt.savefig('foo.pdf') |
将分别给出光栅化或矢量化的输出,这两种方法都很有用。此外,您会发现
1 | savefig('foo.png', bbox_inches='tight') |
正如其他人所说,
然而,我发现在某些情况下(例如,Spyder的
1 2 3 4 5 | 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 |
解决方案是:
1 | pylab.savefig('foo.png') |
刚刚在Matplotlib文档中找到了这个链接,它正好解决了这个问题:http://matplotlib.org/faq/howto ou faq.html生成-images-without-having-a-window-appear
他们说,防止数字出现的最简单方法是通过
1 2 3 4 5 | import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt plt.plot([1,2,3]) plt.savefig('myfig') |
我个人还是更喜欢使用
更新:对于Spyder,您通常不能这样设置后端(因为Spyder通常会提前加载matplotlib,阻止您使用
相反,使用
从这两个提示:一,二
如果您不喜欢"当前"图形的概念,请执行以下操作:
1 2 3 4 | import matplotlib.image as mpimg img = mpimg.imread("src.png") mpimg.imsave("out.png", img) |
其他答案是正确的。但是,有时我会发现我想稍后打开图形对象。例如,我可能希望更改标签大小、添加网格或进行其他处理。在一个完美的世界中,我只需重新运行生成绘图的代码,并调整设置。唉,这个世界并不完美。因此,除了保存到PDF或PNG之外,我还添加了:
1 2 | with open('some_file.pkl',"wb") as fp: pickle.dump(fig, fp, protocol=4) |
像这样,我可以稍后加载figure对象并根据需要操作设置。
我还为堆栈中的每个函数/方法编写了带有源代码和
注意:要小心,因为有时这个方法会生成巨大的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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() |
使用plot()和其他函数创建所需内容后,可以使用类似这样的子句在打印到屏幕或文件之间进行选择:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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() |
我使用了以下方法:
1 2 3 4 5 6 7 8 9 10 | 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非常重要,否则它将不起作用。
您可以这样做:
1 2 | plt.show(hold=False) plt.savefig('name.pdf') |
记住在关闭GUI绘图之前让savefig完成。这样你就可以事先看到图像。
或者,您可以使用
或者,您可以使用
1 2 3 4 | fig, ax = plt.figure(nrows=1, ncols=1) plt.plot(...) plt.show() fig.savefig('out.pdf') |
如果与我一样使用Spyder IDE,则必须禁用交互模式:
(此命令在科学启动时自动启动)
如果要再次启用,请使用:
解决方案:
1 2 3 4 5 6 7 8 9 10 | 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') |
如果要显示图像并保存图像,请使用:
1 | %matplotlib inline |
之后
根据问题matplotlib(pyplot),savefig输出空白图像。
有一点需要注意:如果你使用
一个详细的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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() |
1 2 | #write the code for the plot plt.savefig("filename.png") |
该文件将与运行的python/jupyter文件保存在同一目录中。
1 2 | import matplotlib.pyplot as plt plt.savefig("image.png") |
在Jupyter笔记本中,您必须删除
考虑到今天(这个问题提出时不可用)许多人使用jupyter笔记本作为python控制台,有一种非常简单的方法可以将绘图保存为