以下内容主要学习自《利用Python进行数据分析》
第9章 绘图与可视化
信息的可视化是数据分析中最重要的任务之一,因为可视化是数据探索过程的一部分,例如:帮助识别异常值或所需的数据交换,或者为建模提供一些想法。
matplotlib由John Hunter于2002年发起,目的是在Python环境下进行MATLAB风格的绘图。matplotlib支持所有操作系统上的各种GUI后端,还可以将可视化结果导出为常见的矢量和位图格式(SVG、JPG、PNG、GIF、PDF等)。
如果想在Jupyter notebook中使用交互式绘图,首先需要在Jupyter notebook中输入如下语句:
% matplotlib notebook
简明matplotlib API入门
在使用matplotlib时,我们使用如下的导入惯例:
In [1]: import matplotlib.pyplot as plt
如下的代码会使用默认的设置绘制一个最简单的图形:
In [2]: import numpy as np
In [3]: data = np.arange(10)
In [4]: data
Out[4]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [5]: plt.plot(data)
Out[5]: []
# 显示绘图结果
In [6]: plt.show()
得到的图形如下:
本笔记只记录了关键的特性,如果要深入matplotlib,那么它的可视化作品库和文档是学习高级功能的最佳资源。
图片与子图
matplotlib所绘制的图在Figure对象
中,使用该对象的add_subplot方法
可以创建一个或多个子图。
In [1]: import matplotlib.pyplot as plt
In [2]: import numpy as np
In [3]: fig = plt.figure()
In [4]: ax1 = fig.add_subplot(2, 2, 1)
In [5]: ax2 = fig.add_subplot(2, 2, 2)
In [6]: ax3 = fig.add_subplot(2, 2, 3)
# 用numpy生成一个随机漫步的数据集
In [7]: data = np.random.randn(50).cumsum()
# 用黑色分段线绘制图形
In [8]: plt.plot(data, 'k--')
In [9]: plt.show()
上面代码的意思是图片应该是2X2的(最多4个图形),接着创建了3个子图(序号从1开始),执行后可以看到如下图形。
观察如上的图片,可以得出:如不特别指明,matplotlib会在最后一个子图上进行绘图。
由于创建子图是非常常见的任务,所以matplotlib提供了一个便捷的plt.subplots方法
创建多子图的图形,该方法返回了包含子图对象的Numpy数组。
In [1]: fig, axes = plt.subplots(2,2)
In [2]: axes.size
Out[2]: 4
# 用黑色分段线绘制图形,在最后一个子图上绘制。
In [3]: plt.plot(np.random.randn(50).cumsum(), 'k--')
Out[3]: []
# 在第1个子图上绘制柱状图
In [4]: axes[0,0].hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
# 在第2个子图上绘制散点图
In [5]: axes[0,1].scatter(np.arange(30), np.arange(30) +3 * np.random.randn(30))
In [6]: plt.show()
执行后得到如下的图形。
调整子图的间距
默认情况下,matplotlib会在子图的外部和子图之间留出一定的间距,可以使用subplots_adjust方法
更改间距,该方法的完整声明如下:
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
其中wspace和hspace分别控制了子图间的间距。
In [1]: fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
In [2]: for i in range(2):
...: for j in range(2):
...: axes[i,j].hist(np.random.randn(500), bins=50, color='#0000ff', alpha=0.75)
In [3]: plt.subplots_adjust(wspace=0, hspace=0)
In [4]: plt.show()
上面的代码中,通过设置sharex
和sharey
来表明子图拥有相同的x轴、y轴,当在相同的比例下进行数据对比时,这非常有用。执行后得到如下的图形。
颜色、标记和线类型
matplotlib的plot方法
接收带有x和y轴的数组以及一些可选的字符串缩写参数来指明颜色、线类型。例如,要用绿色破折号绘制,需要执行如下代码:
ax.plot(x, y, 'g--')
与上面同样效果的、更为易懂的代码是:
ax.plot(x, y, linstyle='--', color='g')
除了可以使用颜色缩写,还可以使用十六进制颜色代码(如#ff0000)来指定颜色。参考plot函数
的说明文档可以看到全部线类型。
折线图还可以有标记来凸显实际的数据点,如下:
In [1]: from numpy.random import randn
In [2]: import matplotlib.pyplot as plt
In [3]: plt.plot(randn(30).cumsum(), 'ko--')
Out[3]: []
In [4]: plt.show()
以上第3行代码的等价代码(更容易理解的代码)是:
plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
执行后得到如下的图形
你会注意到,折线图默认会在两个数据点之间线性内插绘制,可以通过drawstyle
选项进行更改,参考如下代码:
In [1]: data = np.random.randn(30).cumsum()
In [2]: plt.plot(data, 'k--', label='Default')
Out[2]: []
In [3]: plt.plot(data, 'b-', drawstyle='steps-post', label='steps-
...: post')
Out[3]: []
In [4]: plt.legend(loc='best')
Out[4]:
In [5]: plt.show()
上面的代码中,我们还设置了label参数
,并且使用plt.legend方法
生成了用于区分的图例,如果你不挑剔,使用loc='best'
会自动选择最合适的位置。效果如下。
刻度、标签
为了讲解轴的自定义,先用如下代码绘制一个随机漫步图:
In [1]: fig = plt.figure()
In [2]: ax = fig.add_subplot(1,1,1)
In [3]: data = np.random.randn(1000).cumsum()
In [4]: ax.plot(data)
Out[4]: []
In [5]: plt.show()
运行后的效果如下
我们用set_xticks方法
和set_xticklabels方法
来改变x轴的刻度,代码如下:
In [1]: fig = plt.figure()
In [2]: ax = fig.add_subplot(1,1,1)
In [3]: ax.plot(data)
Out[3]: []
In [4]: ticks = ax.set_xticks([0,250,500,750,1000])
In [5]: labels = ax.set_xticklabels(['one','two','three','four','f
...: ive'], rotation=30, fontsize='small')
# 为图形设置标题
In [6]: ax.set_title('My first matplotlab plot')
Out[6]: Text(0.5, 1.0, 'My first matplotlab plot')
# 为x轴设置标题
In [7]: ax.set_xlabel('Stages')
Out[7]: Text(0.5, 0, 'Stages')
In [8]: plt.show()
调整后的代码执行效果如下
将图片保存到文件
可以使用plt.savefig方法
将图片保存到文件(figure对象也有同名的实例方法),例如将图片保存为SVG,你只需要输入如下代码:
plt.savefig('figpath.svg')
保存的文件类型是从文件扩展名推断出来的。几个重要的选项参数有:
- dpi,控制每英寸点数分辨率;
- bbox_inches,修剪图形的空白。
例如,为了得到一个png图片,且使用最小的空白,拥有400DPI,那么代码如下:
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')
matplotlib设置
几乎所有的matplotlib默认设置都可以通过全局参数来定制,包括图形大小、子图间距、颜色、字体大小和网格样式等。使用rc方法
是编程修改配置的一种方式。例如,要将全局默认的数字大小设置为10X10,可以输入:
plt.rc('figure', figsize=(10,10))
rc的第一个参数是想要自定义的配置,如figure、axes、xtick、ytick、grid、legend等。如果要变更的设置较多,可以使用字典对象,让代码更加易读:
font_options = {'family': 'monospace',
'weight': 'blod',
'size': 'small'}
plt.rc('font', **font_options)
如果需要更深入的理解和定制全局参数,可以参考matplotlib的配置文件matplotlibrc
,该文件位于matplotlib/mpl-data
路径下。matplotlib的官方网址是https://matplotlib.org。