2012-03-08 77 views
645

我在写一个快速而肮脏的脚本来即时生成绘图。我使用下面的代码(从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 

我不想在GUI上显示的情节,相反,我想情节保存到一个文件(比如说FOO例如,它可以在批处理脚本中使用。我怎么做?

+69

看起来像我找到了答案:其pylab.savefig( 'foo.png') – 2012-03-08 17:42:51

+1

链接也许应该链接到某处matplotlib.org? – 2015-12-10 19:40:41

+20

如果不使用pylab,图形对象也有一个'savefig'方法。所以你可以调用'fig = plt.figure()'然后'fig.savefig(...)'。 – 2015-12-10 19:43:10

回答

782

虽然问题已经回答了,我想用savefig时添加一些有用的提示。文件格式可以通过扩展名指定:

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

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

savefig('foo.png', bbox_inches='tight') 
+1

时显示。是否可以更改生成的图像的尺寸? – Llamageddon 2013-10-28 21:15:25

+14

@Asmageddon在'plt.savefig'中,您可以更改dpi,请参阅答案中的链接。创建图形时可以控制尺寸,请参阅http://matplotlib.org/api/figure_api.html#matplotlib.figure中的figsize。图 – Hooked 2013-10-29 00:46:12

+0

@Hooked plt。savefig保存了这个数字,但并不妨碍显示它。即使当我离开plt.show()时,也会显示数字。我怎样才能防止呢? – MoTSCHIGGE 2014-08-20 11:46:08

114

解决的办法是:

pylab.savefig('foo.png') 
28

如果你不喜欢“当前”数字的概念,这样做:

import matplotlib.image as mpimg 

img = mpimg.imread("src.png") 
mpimg.imsave("out.png", img) 
+1

这不是只是将'src.png'复制到'out.png'吗? – gerrit 2016-05-26 11:44:18

+0

这只是一个例子,它显示了如果你有一个图像对象('img'),那么你可以用'.imsave()'方法将它保存到文件中。 – 2016-05-26 23:29:52

+2

@ wonder.mice将有助于展示如何在不使用当前图形的情况下创建图像。 – scry 2016-08-10 06:50:40

90

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

但是我发现在某些情况下(例如Spyder有plt.ion():交互模式=开启),总是会显示数字。我解决这迫使我在巨大的循环图窗口的关闭,所以我在循环过程中不会有一百万开放数字:

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 
+4

你也可以设置'plt.ioff()#交互绘图模式',但是如果你的代码退出时出错并且可能会禁用你想要使用的行为。 – Demis 2015-12-14 19:04:35

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

如果像我一样,你可以使用Spyder的IDE ,你有禁用交互模式:

plt.ioff()

(该命令会自动以科学的启动时启动)

如果要启用再次,使用:

plt.ion()

46

刚刚发现正是解决这一问题的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),从此以后你要隐藏某些人物(一环时的选项),但仍显示环后数据处理的数字。它可能比选择非交互式后端要慢 - 如果有人测试过,会很有趣。

8

解决方案:

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

13

我用下面的:

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

19

其他答案都是正确的。不过,我有时会发现我想打开后面的图对象。例如,我可能想要更改标签大小,添加网格或执行其他处理。在一个完美的世界中,我只会重新运行生成剧情的代码,并调整设置。唉,这个世界并不完美。因此,除了保存为PDF或PNG,我补充一下:

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

这样,我以后可以加载图形对象和操作设置为我高兴。

我还写出了堆栈中的每个函数/方法的源代码和locals()字典,以便我可以稍后确切地说出生成该图的内容。

注意:小心,因为有时这种方法会生成大文件。

+0

在jupyter笔记本上进行开发会不会更容易,数据在线?通过这种方式,您可以精确跟踪历史记录,甚至可以重新运行它。 – 2017-12-04 14:55:53

+0

@CiprianTomoiaga我从来没有从交互式Python shell(Jupyter或其他)生成生产图。我从脚本中绘制了所有图。 – gerrit 2017-12-05 23:42:25

15

使用图()等函数来创建你想要的内容后,您可以使用一个条款这样绘制到屏幕之间进行选择或文件:

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

你可以这样做:

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

并记得在关闭GUI图之前让savefig完成。这样你可以事先看到图像。

或者,你可以看看它与plt.show() 然后关闭GUI,并再次运行该脚本,但这次plt.savefig()更换plt.show()

或者,你可以使用

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

得到了一个意外的关键字参数'hold' – amitdatta 2017-12-06 01:36:23

相关问题