Python有许多可视化工具,但是我主要讲解matplotlib(http://matplotlib.sourceforge.net)。此外,还可以利用诸如d3.js(http://d3js.org/)之类的工具为Web应用构建交互式图像。
matplotlib是一个用于创建出版质量图表的桌面绘图包(主要是2D方面)。该项目是由John Hunter于2002年启动的,其目的是为Python构建一个MATLAB式的绘图接口。如果结合使用一种GUI工具包(如IPython),matplotlib还具有诸如缩放和平移等交互功能。它不仅支持各种操作系统上许多不同的GUI后端,而且还能将图片导出为各种常见的矢量(vector)和光栅(raster)图:PDF、SVG、JPG、PNG、BMP、GIF等。
matplotlib还有许多插件工具集,如用于3D图形的mplot3d以及用于地图和投影的basemap。要使用本章中的代码示例,请确保你的IPython是以Pylab模式启动的(ipython --pylab),或通过%gui魔术命令打开了GUI事件循环集成。
1、matplotlib API入门
使用matplotlib的办法有很多种,最常用的方式是Python模式的IPython(ipython -pylab)。这样会将IPython配置为使用你所指定的matplotlib GUI后端(Tk、wxPython、PyQt、Mac OS X native、GTK)。对大部分用户而言,默认的后端就已经够用了。Pylab模式还会向IPython引入一大堆模块和函数以提供一种更接近于MATLAB的界面。绘制一张简单的图表即可测试是否一切准备就绪:
如果一切都没有问题,就会弹出一个新窗口,其中绘制的是一条直线。你可以用鼠标或输入close()来关闭它。matplotlib API函数(如plot和close)都位于matplotlib.pyllot模块中,其通常的引入约定是:
1.
In [
2
]:
import
matplotlib.pyplot as plt
2、Figure和Subplot
matplotlib的图像都位于Figure对象中。你可以用plt.figure创建一个新的Figure:
1.
In [
3
]: fig = plt.figure()
不能通过空Figure绘图。必须用add_subplot创建一个或多个subplot才行:
1.
In [
4
]: ax1 = fig.add_subplot(
2
,
2
,
1
)
如果这时发出一条绘图命令哪个(如plt.plot([1.5, 3.5, -2, 1.6])),matplotlib就会在最后一个用过的subplot(如果没有则创建一个)上进行绘制。因此,如果我们执行下列命令,你就会得到如下所示的效果:
“k--”是一个线型选项,用于告诉matplotlib绘制黑色虚线图。上面那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其他空着的格子里面画图了,如下所示:
1.
In [
9
]: _ = ax1.hist(randn(
100
), bins=
20
, color=
'k'
, alpha=
0.3
)
2.
3.
In [
10
]: ax2.scatter(np.arange(
30
), np.arange(
30
) +
3
* randn(
30
))
4.
Out[
10
]: <matplotlib.collections.PathCollection at
0xa8201cc
>
你可以在matplotlib的文档中找到各种图标类型。由于根据特定布局创建Figure和subplot是一件非常常见的任务,于是便出现了一个更为方便的方法(plt.subplots),它可以创建一个新的Figure,并返回一个含有已创建的subplot对象的NumPy数组:
01.
In [
13
]: fig, axes = plt.subplots(
2
,
3
)
02.
03.
In [
14
]: axes
04.
Out[
14
]:
05.
array([[<matplotlib.axes.AxesSubplot object at
0xa76c7ec
>,
06.
<matplotlib.axes.AxesSubplot object at
0xae8f1ec
>,
07.
<matplotlib.axes.AxesSubplot object at
0xb40bc8c
>],
08.
[<matplotlib.axes.AxesSubplot object at
0xb5b7dac
>,
09.
<matplotlib.axes.AxesSubplot object at
0xadf680c
>,
10.
<matplotlib.axes.AxesSubplot object at
0xad6222c
>]], dtype=object)
3、调整subplot周围的间距
默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像的大小(不管是编程还是手工),间距也会自动调整。利用Figure的subplots_adjust方法可以轻而易举地修改间距,此外,它也是个顶级函数:
1.
In [
15
]: subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
不难看出,其中的轴标签重叠了。matplotlib不会检查标签是否重叠,所以对于这种情况,你只能自己设定刻度位置和刻度标签。
4、颜色、标记和线型
matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写。例如,穴ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq4+b7deLrNebvm1sbCzMmr0OnP36OsxOO/ydLU1rTQ0Mjnz8K0+sLro7o8L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;">In [18]: ax.plot(x, y, 'g--')这种在一个字符串中指定颜色和线型的方式非常方便。通过下面这种更为明确的方式也能得到同样的效果:
1.
In [
19
]: ax.plot(x, y, linestyle=
'--'
, color=
'g'
)
线型图还可以加上一些标记(marker),以强调实际的数据点。由于matplotlib创建的是连续的线型图(点与点之间插值),因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面。
1.
In [
20
]: plt.plot(randn(
30
).cumsum(),
'ko--'
)
2.
Out[
20
]: [<matplotlib.lines.Line2D at
0xb86924c
>]
还可以将其写成更为明确的形式:
1.
In [
19
]: plot(randn(
30
).cumsum(), color=
'k'
, linestyle=
'dashed'
, marker=
'o'
)
01.
In [
18
]: plt.plot(randn(
30
).cumsum(),
'ko--'
)
02.
Out[
18
]: [<matplotlib.lines.Line2D at
0xb86924c
>]
03.
04.
In [
19
]: data = randn(
30
).cumsum()
05.
06.
In [
20
]: plt.plot(data,
'k--'
, label=
'Default'
)
07.
Out[
20
]: [<matplotlib.lines.Line2D at
0xba62c8c
>]
08.
09.
In [
21
]: plt.plot(data,
'k--'
, drawstyle=
'steps-post'
, label=
'steps-post'
)
10.
Out[
21
]: [<matplotlib.lines.Line2D at
0xba758ac
>]
11.
12.
In [
22
]: plt.legend(loc=
'best'
)
13.
Out[
22
]: <matplotlib.legend.Legend at
0xba75bcc
>
5、刻度、标签和图例
对于大多数的图表装饰项,其主要实现方式有二:使用过程型的pyplot接口以及更为面向对象的原生matplotlib API。pyplot接口的设计目的就是交互式作用,含有诸如xlim、xticks和xticklabels之类的方法。它们分别控制图表的范围、刻度位置、刻度标签等。其使用方式有以下两种:
调用时不带参数,则返回当前的参数值。例如,plt.xlim()返回当前的X轴绘图范围。调用时带参数,则设置参数值。因此,plt.xlim([0, 10])会将X轴的范围设置为0到10。所有这些方法都是对当前或最近创建的AxesSubplot起作用的。它们各自对应subplot对象上的两个方法,以xlim为例,就是ax.get_xlim和ax.set_xlim。我更喜欢使用subplot的实例方法,当然你完全可以选择自己觉得方便的那个。
(1)设置标题、轴标签、刻度以及刻度标签
为了说明轴的自定义,我将创建一个简单的图像并绘制一段随机漫步:
1.
In [
23
]: fig = plt.figure();
2.
3.
In [
24
]: ax = fig.add_subplot(
1
,
1
,
1
)
4.
5.
In [
25
]: ax.plot(randn(
1000
).cumsum())
6.
Out[
25
]: [<matplotlib.lines.Line2D at
0xbc4da6c
>]
要修改X轴的刻度,最简单的办法是使用set_xticks和set_xticklabels。前者告诉matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值用作标签:
01.
In [
28
]: fig = plt.figure();
02.
03.
In [
29
]: ax = fig.add_subplot(
1
,
1
,
1
)
04.
05.
In [
30
]: ax.plot(randn(
1000
).cumsum())
06.
Out[
30
]: [<matplotlib.lines.Line2D at
0xbd4684c
>]
07.
08.
In [
31
]: ticks = ax.set_xticks([
0
,
250
,
500
,
750
,
1000
])
09.
10.
In [
32
]: labels = ax.set_xticklabels([
'one'
,
'two'
,
'three'
,
'four'
,
'five'
], rotation=
30
, fontsize=
'small'
)
11.
12.
In [
33
]: ax.set_title(
'My first matplotlib plot'
)
13.
Out[
33
]: <matplotlib.text.Text at
0xbd1ed0c
>
14.
15.
In [
34
]: ax.set_xlabel(
'Stages'
)
16.
Out[
34
]: <matplotlib.text.Text at
0xba911cc
>
Y轴的修改方式与此类似,只需将上述代码中的x替换为y即可。
(2)添加图例
图例(legend)是另一种用于标识图表元素的重穴ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq5pL7foaPM7bzTzbzA/bXEt73KvdPQtv6ho9fuvPK1pbXEysfU2sztvNNzdWJwbG90tcTKsbrytKvI62xhYmVsss7K/aO6PC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">In [35]: fig = plt.figure(); ax = fig.add_subplot(1, 1, 1)In [36]: ax.plot(randn(1000).cumsum(), 'k', label='one')Out[36]: [<matplotlib.lines.Line2D at 0xc0e49cc>]In [37]: ax.plot(randn(1000).cumsum(), 'k--', label='two')Out[37]: [<matplotlib.lines.Line2D at 0xc0e7e2c>]In [38]: ax.plot(randn(1000).cumsum(), 'k.', label='three')Out[38]: [<matplotlib.lines.Line2D at 0xc0f238c>]在此之后,你可以调用ax.legend()或plt.legend()来自动创建图例:
1.
In [
40
]: ax.legend(loc=
'best'
)
2.
Out[
40
]: <matplotlib.legend.Legend at
0xc0e7dcc
>
联系客服