matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。
它的文档相当完备,并且Gallery页面中有上百幅缩略图,打开之后都有源程序。因此如果你需要绘制某种类型的图,只需要在这个页面中浏览/复制/粘贴一下,基本上都能搞定。
在Linux下比较著名的数据图工具还有gnuplot,这个是免费的,Python有一个包可以调用gnuplot,但是语法比较不习惯,而且画图质量不高。
而 Matplotlib则比较强:Matlab的语法、python语言、latex的画图质量(还可以使用内嵌的latex引擎绘制的数学公式)。
matplotlib实际上是一套面向对象的绘图库,它所绘制的图表中的每个绘图元素,例如线条Line2D、文字Text、刻度等在内存中都有一个对象与之对应。
-
numpy
$ sudo pip install numpy
-
matplotlib
$ sudo pip install matplotlib
-
python-tk
$ sudo install apt-get python-tk
import numpy as np
import matplotlib.pyplot as plt ❶
x = np.linspace(0, 10, 1000)
y = np.sin(x)
z = np.cos(x**2)
plt.figure(figsize=(8,4)) ❷
plt.plot(x,y,label="$sin(x)$",color="red",linewidth=2) ❸
plt.plot(x,z,"b--",label="$cos(x^2)$") ❹
plt.xlabel("Time(s)") ❺
plt.ylabel("Volt")
plt.title("PyPlot First Example")
plt.ylim(-1.2,1.2)
plt.legend()
plt.show() ❻
上述代码的图为:
❶ pylab模块
matplotlib还提供了一个名为pylab的模块,其中包括了许多NumPy和pyplot模块中常用的函数,方便用户快速进行计算和绘图,十分适合在IPython交互式环境中使用。本书使用下面的方式载入pylab模块:
>>> import pylab as pl
❷调用figure()创建一个Figure(图表)对象,并且它将设为当前Figure对象。也可以不创建Figure对象直接调用接下来的plot()进行绘图,这时matplotlib会自动创建一个Figure对象。figsize参数指定Figure对象的宽度和高度,其单位为英寸。此外还可以用dpi参数指定Figure对象的分辨率,即每英寸所表示的像素数,这里使用缺省值80。因此本例中所创建的Figure对象的宽度为“8*80 = 640”
个像素。但是在显示出绘图窗口之后,用工具栏中的保存按钮将图表保存为图像时,所保存的图像的大小是“800*400”像素。这是因为保存图像时会使用不同的dpi设置。这个设置保存在matplotlib的配置文件中
❸创建Figure对象之后,接下来调用plot()在当前的Figure对象中绘图。实际上plot()是在Axes(子图)对象上绘图,如果当前的Figure对象中没有Axes对象,将会为之创建一个几乎充满整个图表的Axes对象,并且使此Axes对象成为当前的Axes对象。plot()的前两个参数是分别表示X、Y轴数据的对象,这里使用的是NumPy数组。使用关键字参数可以指定所绘制的曲线的各种属性:
- label:给曲线指定一个标签名称,此标签将在图示中显示。如果标签字符串的前后有字符’$’,则matplotlib会使用其内嵌的LaTex引擎将其显示为数学公式。(LaTex引擎会降低绘图数据)
- color:指定曲线的颜色,颜色可以用英文单词,或者以’#’字符开头的三个16进制数,例如’#ff0000’表示红色。或者使用值在0到1范围之内的三个元素的元组表示,例如(1.0, 0.0, 0.0)也表示红色。
- linewidth:指定曲线的宽度,可以不是整数,也可以使用缩写形式的参数名lw。
❹直接通过第三个参数’b–’指定曲线的颜色和线型,它通过一些易记的符号指定曲线的样式。其中’b’表示蓝色,’–’表示线型为虚线。在IPython中输入“plt.plot?”可以查看格式化字符串以及各个参数的详细说明。
❺接下来通过一系列函数设置当前Axes对象的各个属性:
- xlabel、ylabel:分别设置X、Y轴的标题文字。
- title:设置子图的标题。
- xlim、ylim:分别设置X、Y轴的显示范围。
- legend:显示图示,即图中表示每条曲线的标签(label)和样式的矩形区域。
❻最后调用plt.show()显示出绘图窗口。在通常的运行情况下,show()将会阻塞程序的运行,直到用户关闭绘图窗口。然而在带“-wthread”等参数的IPython环境下,show()不会等待窗口关闭。
还可以调用plt.savefig()将当前的Figure对象保存成图像文件,图像格式由图像文件的扩展名决定。下面的程序将当前的图表保存为“test.png”,并且通过dpi参数指定图像的分辨率为120,因此输出图像的宽度为“8*120 = 960”个像素。
>>> plt.savefig("test.png", dpi=120)
**注意:**服务器模式时要加入下列代码:
import matplotlib
matplotlib.use('Agg')
savefig()的第一个参数可以是文件名,也可以是和Python的文件对象有相同调用接口的对象。例如可以将图像保存到StringIO对象中,这样就得到了一个表示图像内容的字符串。这里需要使用fmt参数指定保存的图像格式。
>>> from StringIO import StringIO
>>> buf = StringIO() # 创建一个用来保存图像内容的StringIO对象
>>> plt.savefig(buf, fmt="png") # 将图像以png格式保存进buf中
>>> buf.getvalue()[:20] # 显示图像内容的前20个字节
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 '
##4. 面向对象方式绘图
为了方便快速绘图matplotlib通过pyplot模块提供了一套和MATLAB类似的绘图API,将众多绘图对象所构成的复杂结构隐藏在这套API内部。我们只需要调用pyplot模块所提供的函数就可以实现快速绘图以及设置图表的各种细节。pyplot模块虽然用法简单,但不适合在较大的应用程序中使用。
当前的图表和子图可以使用plt.gcf()和plt.gca()获得,分别表示"Get Current Figure"和"Get Current Axes"。在pyplot模块中,许多函数都是对当前的Figure或Axes对象进行处理,比如说:
plt.plot()实际上会通过plt.gca()获得当前的Axes对象ax,然后再调用ax.plot()方法实现真正的绘图。
可以在Ipython中输入类似"plt.plot??"的命令查看pyplot模块的函数是如何对各种绘图对象进行包装的。