信息可视化(也叫绘图)是数据分析中最重要的工作之一。Python有许多库进行静态或动态的数据可视化,但这里主要关注matplotlib和基于它的库。
matplotlib
是一个用于创建出版质量图表的桌面绘图包(主要是2D方面)。该项目是由John Hunter于2002年启动的,其目的是为Python
构建一个MATLAB
式的绘图接口。matplotlib
和IPython
社区进行合作,简化了从IPython shell
(包括现在的Jupyter notebook
)进行交互式绘图。matplotlib
支持各种操作系统上许多不同的GUI后端,而且还能将图片导出为各种常见的矢量(vector)和光栅(raster)图:PDF、SVG、JPG、PNG、BMP、GIF等。除了几张,本书中的大部分图都是用它生成的。
对于创建用于打印或网页的静态图形,我建议默认使用matplotlib
和附加的库,比如pandas
和seaborn
。对于交互式图形以便在Web上发布,可以使用Plotly和Boken
学习本章代码案例的最简单方法是在Jupyter notebook
进行交互式绘图。在Jupyter notebook中执行下面的语句:%matplotlib notebook
一、matplotlib API 入门
- 引入
matplotlib
,并创建简单的图形
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(10)
plt.plot(data)
虽然seaborn
这样的库和pandas
的内置绘图函数能够处理许多普通的绘图任务,但如果需要自定义一些高级功能的话就必须学习matplotlib
API。matplotlib
的示例库和文档是学习高级特性的最好资源。
matplotlib
的图像都位于Figure对象中。你可以用plt.figure
创建一个新的Figure,但不能通过空Figure绘图。必须用add_subplot
创建一个或多个subplot
才行:
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
plt.plot(np.random.randn(50).cumsum(), 'k--') # 在最后一个用过的subplot上进行绘制,隐藏创建figure和subplot的过程
提示:使用Jupyter notebook有一点不同,即每个小窗重新执行后,图形会被重置。因此,对于复杂的图形,,你必须将所有的绘图命令存在一个小窗里。
由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其它空着的格子里面画图了
ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
plt.subplots
,它可以创建一个新的Figure,并返回一个含有已创建的subplot
对象的NumPy
数组:fig, axes = plt.subplots(2, 3)
。可以轻松地对axes数组进行索引,就好像是一个二维数组一样,例如axes[0,1]。还可以通过sharex
和sharey
指定subplot
应该具有相同的X轴或Y轴。在比较相同范围的数据时,这也是非常实用的,否则,matplotlib
会自动缩放各图表的界限。
- 利用Figure的
subplots_adjust
(也是个顶级函数)方法可以轻而易举地修改间距:subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
,其中wspace
和hspace
用于控制宽度和高度的百分比,可以用作subplot
之间的间距。 - 在
plot
函数中可以通过字符串来指定颜色和线型:ax.plot(x, y,'g--')
这种更为明确的方式也能得到同样的效果:ax.plot(x, y, linestyle='--', color='g')
常用的颜色可以使用颜色缩写,也可以指定颜色码(例如,#CECECE
)
在
IPython
和Jupyter
中使用plot?
可以查看文档说明。
- 线图可以使用标记强调数据点。因为
matplotlib
可以创建连续线图,在点之间进行插值,因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面:
from numpy.random import randn
plt.plot(randn(30).cumsum(), 'ko--')
plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
- 在线型图中,非实际数据点默认是按线性方式插值的。可以通过
drawstyle
选项修改
data = np.random.randn(30).cumsum()
plt.plot(data,'k--', label='Default')
plt.plot(data,'k-', drawstyle='steps-post', label='steps-post')
plt.legend(loc='best')
笔记:你必须调用plt.legend(或使用ax.legend,如果引用了轴的话)来创建图例,无论你绘图时是否传递label标签选项。
- pyplot接口的设计目的就是交互式使用,含有诸如
xlim
、xticks
和xticklabels
之类的方法。它们分别控制图表的范围、刻度位置、刻度标签等。其使用方式有以下两种:
- 调用时不带参数,则返回当前的参数值(例如,
plt.xlim()
返回当前的X轴绘图范围)。 - 调用时带参数,则设置参数值(例如,
plt.xlim([0,10])
会将X轴的范围设置为0到10)。
所有这些方法都是对当前或最近创建的AxesSubplot
起作用的。它们各自对应subplot
对象上的两个方法,以xlim
为例,就是ax.get_xlim
和ax.set_xlim
。
- 设置标题、轴标签、刻度以及刻度标签
fig = plt.figure(