第6章 数据可视化
6.1 Matplotlib 基础知识
Matplotlib 简介
Python 的可视化库众多,这里之所以选择 Matplotlib,是因为它是 Python 中最基础、应用最广泛的可视化库,而且自由度非常高,可以轻松绘制各种图,从简单的折线图到复杂的热力图都不在话下,还能够灵活地设置图的任何元素,包括颜色、样式、标签、网格线等。
可视化的关键步骤
Matplotlib 自由度极高,这无疑是它的一大优点。然而,高自由度也意味着参数非常复杂,以至于一种结果有多种实现方式,导致很多初学者一个个知识点啃得很痛苦,还总是学完就忘。
所以,我带大家用一种新的方式来学习 Matplotlib,知其然并探其所以然。在正式画图之前,我们先来思考一个问题:手工画一幅折线图有哪些关键步骤?
1)创建画布。既然要画图,首先要确定在哪里作图,例如一张白纸,也就是画布。
2)设置坐标轴。常见图表以二维为主,其坐标轴为 x 轴和 y 轴,根据数据确定好对应坐标轴的刻度,并标注清楚 x 和 y 轴的名称,同时可以给图起个标题。
3)画图。在确定好的坐标轴基础上,把源数据画成折线的形式。同时可以设置折线的样式、颜色、图例,也可以在图上标注每个点具体的数值。
4)润色。例如背景加上网格线,突出峰值的颜色,或者用平均数作为辅助线。
如此一来,一幅手工折线图就画好了。当然,Matplotlib 的学习也是一样的道理。下面,我们就把这几个关键步骤逐一攻克。
6.2 Matplotlib 基础操作
画图前的准备
我们提前导入 Matplotlib 库并进行相关的设置,以避免在作图时报错。
导入画图必备的库 import matplotlib. pyplot as plt
解决中文显示错误的问题 plt. rcParams['font. sans- serif'] = 'SimHei'
让 Matplotlib 在 Jupyter Notebook 中输出高清矢量图%config InlineBackend. figure_format = 'svg'
使画图可以直接在 Jupyter Notebook 中显示%matplotlib inline
创建画布
创建画布,我们直接用 plt. figure():
fig = plt.figure (figsize = (5,3))
只需一行代码就创建好了画布。画布的大小由 figsize 参数控制,大家可以根据实际需求进行设置,这里画布长 5 宽 3(单位:英寸)。
画布并不会直接显示,为了让大家更有感知,这里我们画一个简单的样例数据来展示:
基于两组数据,用 plot()方法在画布上生成了折线图,如图 6- 1 所示。
图 6-1 在整张画布上生成折线图
创建画布就相当于找到了一张白纸,直接用 plot()默认是在整张白纸上画图。不过,我们偶尔也会在一张白纸上画多幅子图,如图 6- 2 所示。
图 6-2 画布和子图的关系
可以在一张画布上创建多幅子图,在每幅子图上绘制对应的图:
fig = plt.figure (figsize = (5,3))
在上面的画布中生成一个 1 行 2 列的子图矩阵(即横向两幅子图),这里选中的是子图 1 ax 1 = plt.subplot (1,2,1)
跟在子图 1 的后面绘制,即在子图 1 上画图 plt.plot ([4,5,6], [2,3,5])
生成一个 1 行 2 列的子图矩阵,并选中子图 2 ax 2 = plt.subplot (1,2,2) 在子图 2 上画图 plt.plot ([1,2,3], [4,5,0])
通过 plt. subplot()创建子图矩阵,并选择在对应的子图上绘图,结果如图 6- 3 所示。
图 6-3 在子图上绘图
子图的创建有很多种方法,这里主要介绍的是 subplot()方法。该方法有 3 个参数,前两个用来指定在画布上创建几行、几列的子图,第 3 个指定在第几个子图上进行绘制。
画图
1. 简单图的绘制
画图之所以放在了绘制坐标轴前面,是因为 Matplotlib 会结合输入的数据,直接按照默认适配的坐标轴画图,并不像我们在中学数学课上画函数曲线一样必须先画好坐标轴。
画图最基本的是要传入数据,一般用列表存储,前面是 x 轴的值,后面是 y 轴的值。以折线图为例,直接向 plt. plot()传入列表值即可:
得到了如图 6- 4 所示的结果。
图 6-4 折线图示例
2. 设置图的参数
默认生成的图有点粗糙,我们可以设置线条的颜色、点和线条的样式:
pythonfig = plt.figure(figsize = (5,3))#color 代表线条颜色,r是红色的缩写#marker 是每个点的样式,o表示用圆圈标记#linestyle 则是线条的样式,这里dashed 代表虚线plt.plot([1,2,3,4],[4,5,1,7],color = 'r',marker = 'o',linestyle = 'dashed')
通过设置线条的颜色、点和线条的样式,折线图的美观度得到大幅提升,如图 6- 5 所示。
图 6-5 调整后的折线图
不同的图,如饼图、散点图、柱状图各自的参数有细微差异,后面会单独绘图进行有针对性的介绍。
设置坐标轴
1. 添加标题
刚才画的图还是太单调,既没有整体的标题,也没有坐标轴的说明,让人根本看不出横纵坐标轴分别代表什么。我们可以进行以下设置:
fig = plt.figure (figsize = (5,3))
添加图的整体标题,size 表示字号大小,color 表示颜色 plt.title ('折线图案例', size = 13, color = 'g')
添加 x 轴标题,labelpad 的数值是标题和 x 轴(或 y 轴)之间的距离 plt.xlabel ('销售额(百万元)', size = 9, labelpad = 15)
添加 y 轴标题 plt.ylabel ('销量(万)', size = 9, labelpad = 10)
plt.plot ([1, 2, 3, 4], [4, 5, 1, 7], color = 'r', marker = 'o', linestyle = 'dashed')
添加整体、x 轴、y 轴标题之后,折线图看上去更加美观了,如图 6- 6 所示。
折线图案例图 6-6 添加标题后的折线图
如果坐标轴刻度内容较多,挤在一起,导致可读性很差,可以通过设置 plt. xtickss(rotation=30)来将坐标轴的刻度旋转一定的角度,这里 rotation 参数等于 30 表示旋转
2. 调整坐标范围
目前
plt.xlim (0,6) plt.ylim (0,10)
最终刻度则随之改变,如图 6- 7 所示。
图 6-7 调整后的
润色
1. 设置图例
我们可以再加一条折线,得到了两条折线的组合图,并添加图例:
为了让坐标轴自适应,这里我们注释掉了范围设置 #plt . xlim (0,7) #plt . ylim (0,10) #原来的折线 ,添加了 label 参数 plt.plot ([1,2,3,4],[4,5,1,7], color = 'r', marker = 'o', linestyle = 'dashed', label = 'xl') #新增的同量纲的折线plt . plot ([1,2,3,4],[6,4,2,4], color = 'g', label = 'x 2') #设置图例plt . legend (loc = 'best') 结果如图6- 8所示。
结果如图 6- 8 所示。
折线图案例图 6-8 生成双折线图并添加图例
先在画图的时候为两条折线设置了 label 参数,参数的值即为图例显示的内容,然后通过 plt. legend()显示图例,loc 参数对应图例显示的位置,值'best'则是让它自己选择最佳位置展示。更多 loc 参数如表 6- 1 所示。
表 6- 1 loc 参数的值及位置描述
参数值 | 位置描述 |
best | 最佳位置(自动选择) |
upper right | 右上角 |
upper left | 左上角 |
lower left | 左下角 |
lower right | 右下角 |
left | 左侧 |
right | 右侧 |
center left | 左侧垂直居中位置 |
center right | 右侧垂直居中位置 |
lower center | 下方水平居中位置 |
upper center | 上方水平居中位置 |
center | 中心位置 |
2. 设置双坐标轴
我们在原折线的基础上增加一条量纲不同的折线,它的 y 值体量更大:
原来的新线 plt. plot([1,2,3,4],[4,5,1,7], color
结果是原来的折线被急剧压缩,如图 6- 9 所示
图 6-9 两条量纲不同的折线
这种情况就需要用到双坐标轴了,画完第一条折线后添加 plt. twinx(),这样第一条折线对应的是左侧的坐标轴,后面的折线对应的是右侧坐标轴:
plt.plot ([1,2,3,4],[4,5,1,7], color = 'r', marker = 'o', linestyle = 'dashed') plt.twinx () # 变成双坐标轴 plt.plot ([1,2,3,4],[400,500,200,300], color = 'g')
运行结果如图 6- 10 所示。
图 6-10 双坐标轴的效果
3. 设置网格线
设置网格线用的是 plt. grid()方法,该方法的主要参数如下。
b:布尔值,用于控制是否显示网格线。True 表示显示网格线,False 表示不显示。
axis:字符串,表示要设置网格线的坐标轴。可选值有'x'(仅设置 x 轴网格线)、'y'(仅设置 y 轴网格线)和'both'(设置 x 轴和 y 轴的网格线)。
linestyle:字符串,表示网格线的样式。常见选项有'(实线)、'(虚线)和'(点线)。
linewidth:数值,表示网格线的宽度。
color:字符串,表示网格线的颜色。
在拥有两条同量纲的折线的图中,根据需求设置 grid 即可:
plt.grid (b = True, axis = 'both', linestyle = '- - '
我们得到显示了 x 轴和 y 轴、样式为虚线的网格线,如图 6- 11 所示。
图 6-11 网格线效果
6.3 绘制常用图形
刚才从画图流程的角度介绍了常用函数及参数的使用,接下来绘制常用图形,强化对 Matplotlib 的理解。
绘制折线图
折线图的绘制上面已经演示过,用的是 plt. plot(),这里我们对它的常用参数做一个汇总:
plt.plot (x, y, color, linestyle, linewidth, marker, markersize, label, alpha)
#x和y对应的是数据列表 #color ,线条颜色,一般填入颜色的缩写,比如 g 是 green 的缩写,r 是 red 的缩写 #linestyle ,线条样式,值'- '代表实线,'- - '代表虚线,'- - '代表点划线,':'代表点状虚线 #linewidth ,线条的粗细,用数值表示 #marker ,每个点的样式,值'0'代表圆圈,'v'代表下三角形,'s'代表正方形,'*'代表星号,'*'代 #表叉号 #markersize ,每个点的大小 #label ,用于生成图例的标签 #alpha ,透明度,值在 0- 1之间,越接近0,越透明
对应 color 参数可以参考表 6- 2 根据需求灵活设置。
表 6-2 常用 color 参数值
参数值 | 颜色 | 描述 |
b | 蓝色 | blue |
g | 绿色 | green |
r | 红色 | red |
c | 青色 | cyan |
m | 品红 | magenta |
y | 黄色 | yellow |
k | 黑色 | black |
w | 白色 | white |
我们画一幅绿色、用点划线构成、每个点是正方形、透明度为 0.8 的折线图:
fig
根据上面的需求绘制折线图 plt.plot (months, product_A, color
具体的标题、坐标轴等设置上一节已经介绍过,在这里我们只关注各种图表本身。上面代码的运行结果如图 6- 12 所示。
图 6-12 根据需求绘制的折线图
绘制柱状图
使用 plt. bar()可以绘制柱状图,示例如下:
柱状图示例数据 fig
上面的代码绘制了一幅红色、柱子宽度为 0.5(width
图 6-13 柱状图示例
柱状图的主要参数及其描述见表 6- 3。
表 6- 3 柱状图的主要参数及其描述
参数 | 描述 | 示例 |
x | x 轴上的类别标签或数值 | x=[& #x27 ; 类别 1& #x27 ;, & #x27 ; 类别 2& #x27 ;, & #x27 ; 类别 3& #x27 ;, & #x27 ; 类别 4& #x27 ;] |
height | y 轴上的值(柱子的高度) | height = [10, 15, 20, 25] |
width | 柱子的宽度,值范围为 0~1 | width = 0.5 |
align | 柱子对齐方式,可选 & #x27 ; center& #x27 ; 或 & #x27 ; edge& #x27 ;(默认为 & #x27 ; center& #x27 ;) | align = & #x27 ; center& #x27 ; |
color | 柱子的颜色(可选) | 和折线图颜色设置一样 |
edgecolor | 柱子边框的颜色(可选) | edgecolor = & #x27 ; K& #x27 ; |
linewidth | 柱子边框的宽度(可选) | linewidth = 1.2 |
绘制散点图
绘制散点图可以用 plt. scatter(),我们直接生成一个散点图示例:
导入 NumPy 是为了用它的随机函数 import numpy as np
fig = plt.figure (figsize = (6,4))
随机生成 25 个点
x = np.random.rand (25) y = np.random.rand (25)
绘制散点图
plt.scatter (x, y, color
运行上面的代码,得到了 25 个点,这些点内部是红色,边缘线是黑色,点的大小固定(size
图 6-14 散点图示例
除了 color 和 alpha 等各类图通用的参数外,散点图的常用参数及其描述可参考表 6- 4。
表 6-4 散点图的常用参数及其描述
参数 | 描述 | 示例 |
x | x 轴上的数据点 | x=np.random.rand (50) |
y | y 轴上的数据点 | y=np.random.rand (50) |
s | 散点的大小(可选) | s=100 |
marker | 散点的形状(可选) | marker=& #x27 ; o& #x27 ; |
linewidth | 散点边缘线的宽度(可选) | linewidth=1.5 |
edgecolor | 散点边缘线的颜色(可选) | edgecolor=& #x27 ; k& #x27 ; |
绘制其他常用图形
Matplotlib 能够绘制各种图形,这些图形的绘制方法虽不相同,但绘制的逻辑是相似的,大家只需要知道绘制的逻辑,在使用时稍加查询就好。其他常用图形的绘制这里不展开,绘制时使用的具体方法见表 6- 5。
表 6-5 绘制其他常用图形时使用的具体方法
图形类型 | 方法 | 描述 |
水平柱状图 | ph.barh () | 绘制水平柱状图,用于比较不同类别的数据 |
饼图 | ph.pie () | 绘制饼图,用于显示各类别的占比关系 |
直方图 | ph.hist () | 绘制直方图,用于显示数据的分布情况 |
(续)
图形类型 | 方法 | 描述 |
箱线图 | ph.boxplot () | 绘制箱线图,用于显示数据的分布和离群点 |
小提琴图 | ph.violinplot () | 绘制小提琴图,用于显示数据的分布及概率密度 |
等高线图 | ph.contour () | 绘制等高线图,用于显示二维平面上的等高线 |
热力图 | ph.imshow () | 绘制热力图,用于显示矩阵或图像数据的强度值 |
6.4 本章小结
在这一章中,我们先从画图的关键步骤出发,学习了 Matplotlib 创建画布、画图、调整坐标轴和润色这些通用的画图技巧。然后通过折线图、柱状图和散点图的实例讲解,对 Matplotlib 图形绘制逻辑和参数有了进一步认知。需要说明的是,面对纷繁复杂的参数,大家千万不要慌,也不用硬记,只需要在用到的时候查找文档就好。