第1章
数据可视化
机器学习中许多时候需要将数据可视化,方便更直观地表现目前的数据,所以本书先介绍数据图形的绘制,所使用的工具是matplotlib绘图库模块,使用前需先安装:
pip install matplotlib
matplotlib是一个庞大的绘图库模块,本章我们只导入其中的pyplot子模块就可以完成许多图表绘制,如下所示,未来就可以使用plt调用相关的方法。
import matplotlib.pyplot as plt
本章将叙述matplotlib的重点内容,完整使用说明可以参考matplotlib的官方网站。
1-1 认识matplotlib.pyplot模块的主要函数
下列是绘制图表的常用函数。
下列是坐标轴设定的常用函数。
下列是图片的读取与储存的函数。
1-2 绘制简单的折线图plot( )
这一节将从最简单的折线图开始解说,常用语法格式如下:
plot(x, y, lw=x, ls=‘x’, label=‘xxx’, color)
x:x轴系列值,如果省略系列自动标记0,1,…,可参考1-2-1节。
y:y轴系列值,可参考1-2-1节。
lw:linewidth的缩写,折线图的线条宽度,可参考1-2-2节。
ls:linestyle的缩写,折线图的线条样式,可参考1-2-6节。
color:缩写是c,可以设定色彩,可参考1-2-6节。
label:图表的标签,可参考1-2-8节。
1-2-1 画线基础实践
将含数据的列表当作参数传给plot( ),列表内的数据会被视为y轴的值,x轴的值会依列表值的索引位置自动产生。
程序实例ch1_1.py:绘制折线,square[ ]列表有9笔数据代表y轴值,数据基本上是x轴索引0~ 8的平方值序列,这个实例使用列表生成式建立x轴数据。
执行结果
在绘制线条时,预设颜色是蓝色,更多相关设定1-2-6节会讲解。如果x轴的数据是0,1,…,n时,在使用plot( )时我们可以省略x轴数据,可以参考下列程序实例。
程序实例ch1_2.py:重新设计ch1_1.py,此实例省略x轴数据。
执行结果
与ch1_1.py相同。
从上述执行结果可以看到左下角的轴刻度不是(0,0),我们可以使用axis( )设定x、y轴的最小和最大刻度。
程序实例ch1_3.py:重新设计ch1_2.py,将x轴刻度设为0~8,y轴刻度设为0~70。
执行结果
在做数据分析时,有时候会想要在图表内增加网格线,这可以让图表中x轴值对应的y轴值更加清楚,可以使用grid( )函数。
程序实例ch1_3_1.py:增加网格线重新设计ch1_3.py,此程序重点是第7行。
执行结果
1-2-2 线条宽度linewidth
使用plot( )时预设线条宽度是1,可以多加一个linewidth(缩写是lw)参数设定线条的粗细。
程序实例ch1_4.py:设定线条宽度是10,使用lw=10。
执行结果
1-2-3 标题的显示
目前matplotlib模块默认不支持中文显示,笔者将在1-5节讲解如何让图表显示中文,下列是几个显示标题的重要方法。
上述方法默认字号大小是12,但是可以使用fontsize参数更改字号。
程序实例ch1_5.py:使用默认字号为图表与x、y轴建立标题。
执行结果
程序实例ch1_6.py:使用设定字号24建立图表标题,字号16建立x、y轴标题。
执行结果
1-2-4 坐标轴刻度的设定
在设计图表时可以使用tick_params( )设计设定坐标轴的刻度大小、颜色以及应用范围。
如果axis的xx是both,代表应用到x轴和y轴;如果xx是x,代表应用到x轴;如果xx是y,代表应用到y轴。color则是设定刻度的线条颜色,例如:red代表红色,1-2-6节将有颜色表。
程序实例ch1_7.py:使用不同刻度与颜色绘制图表。
执行结果
1-2-5 多组数据的应用
目前所有的图表皆是只有一组数据,其实可以扩充多组数据,只要在plot( )内增加数据列表参数即可。此时plot( )的参数如下:
plot(seq, 第一组数据, seq, 第二组数据, … )
程序实例ch1_8:设计含多组数据的图表。
执行结果
上述以不同颜色显示线条是系统默认,我们也可以自定义线条色彩。
1-2-6 线条色彩与样式
如果想设定线条色彩,可以在plot( )内增加下列color颜色参数设定,下列是常见的色彩。
下列是常见的样式。
上述可以混合使用,例如‘r-.’代表红色虚点线。
程序实例ch1_9.py:采用不同色彩与线条样式绘制图表。
执行结果
上述第10行最右边的‘k.’代表绘制黑点而不是绘制线条,读者也可以使用不同颜色绘制散点图,1-3节也会介绍另一个方法scatter( )绘制散点图。上述格式应用是很灵活的,如果我们使用‘-*’可以绘制线条,同时在指定点加上星星标记。注:如果没有设定颜色,系统会自行配置颜色。
程序实例ch1_10.py:重新设计ch1_9.py绘制线条,同时为各个点加上标记,程序重点是第10行。
执行结果
1-2-7 刻度设计
目前,所有图表的x轴和y轴的刻度皆是plot( )方法针对所输入的参数默认设定的,请先参考下列实例。
程序实例ch1_11.py:假设3大品牌车辆2021—2023年的销售数据如下:
Benz 3367 4120 5539
BMW 4000 3590 4423
Lexus 5200 4930 5350
请将上述数据绘制成图表。
执行结果
上述程序最大的遗憾是x轴的刻度,对我们而言,其实只要有2021、2022、2023这3个刻度即可,还好可以使用pyplot模块的xticks( )、yticks( )分别设定x、y轴刻度,可参考下列实例。
程序实例ch1_12.py:重新设计ch1_11.py,自行设定刻度,这个程序的重点是第9行,将seq列表当作参数放在plt.xticks( )内。
执行结果
1-2-8 图例legend( )
本章所建立的图表,应该说已经很好了,缺点是缺乏各种线条代表的意义,在Excel中称图例(legend),下列笔者将直接以实例说明。
程序实例ch1_13.py:为ch1_12.py建立图例。
执行结果
这个程序最大不同在第10~12行,下列是以第10行解释。
上述调用plt.plot( )时需同时设定label,最后使用第13行的方式执行legend( )图例的调用。其中参数loc可以设定图例的位置,可以有下列设定方式:
如果省略loc设定,则使用预设‘best’,在应用时可以使用设定整数值,例如:设定loc=0与上述效果相同。若是顾虑程序可读性,建议使用文字字符串方式设定,当然也可以直接设定数字。
程序实例ch1_13_1.py:在ch1_13.py的基础上省略loc设定。
执行结果 与ch1_13.py相同。
程序实例ch1_13_2.py:在ch1_13.py的基础上设定loc=0。
执行结果 与ch1_13.py相同。
程序实例ch1_13_3.py:在ch1_13.py的基础上设定图例在右上角。
执行结果 下方左图。
程序实例ch1_13_4.py:在ch1_13.py的基础上设定图例在左边中央。
执行结果 如上右图。
经过上述解说,我们已经可以将图例放在图表内了。如果想将图例放在图表外,需要先理解坐标,在图表内左下角位置坐标是(0,0),右上角位置坐标是(1,1),概念如下:
首先需使用bbox_to_anchor( )当作legend( )的一个参数,设定锚点(anchor),也就是图例位置,例如:如果我们想将图例放在图表右上角外侧,需设定loc=‘upper left’,然后设定bbox_to_anchor(1,1)。
程序实例ch1_13_5.py:在ch1_13.py的基础上将图例放在图表右上角外侧。
执行结果 下方左图。
上述最大的缺点是由于图表与Figure 1的留白不足,造成无法完整显示图例。matplotlib模块内有tight_layout( )函数,可利用设定pad参数在图表与Figure 1间设定留白。
程序实例ch1_13_6.py:设定pad=7,重新设计ch1_13_5.py。
执行结果 可参考如上右图。
很明显图例显示不完整的问题改善了。如果将pad改为h_pad/w_pad可以分别设定高度/宽度的留白。
1-2-9 保存与开启文件
图表设计完成,可以使用savef i g( )保存文件,这个方法需放在show( )的前方,表示先储存再显示图表。
程序实例ch1_14.py:扩充ch1_13.py,在屏幕显示图表前,先将图表存入目前文件夹的out1_14.jpg。
执行结果
读者可以在ch1文件夹看到out1_14.jpg文件。
上述plt.savef i g( )中第一个参数是所存的文件名,第二个参数是将图表外多余的空间删除。
要开启文件可以使用matplotlib.image模块,可以参考下列实例。
程序实例ch1_15.py:开启out1_14.jpg文件。
执行结果
上述程序可以顺利开启out1_14.jpg文件。
1-2-10 在图上标记文字
在绘制图表过程中,有时需要在图上标记文字,这时可以使用text( )函数,此函数基本格式如下:
x,y是文字输出的左下角坐标,它不是绝对坐标,是相对坐标,大小会随着坐标刻度增减。
程序实例ch1_15_1.py:增加文字重新设计ch1_3_1.py。
执行结果
1-3 绘制散点图scatter( )
前方介绍了可以使用plot( )绘制散点图,本节将介绍绘制散点图的常用方法scatter( )。
1-3-1 基本散点图的绘制
绘制散点图可以使用scatter( ),基本语法如下(更多参数后面章节会解说):
scatter(x, y, s, c, cmap)
x,y:在(x,y)位置绘图。 c:颜色,可以参考1-2-6节。
s:绘图点的大小,预设是20。 cmap:彩色图表,可以参考1-4-5节。
程序实例ch1_16.py:在坐标轴(5,5)绘制一个点。
执行结果
1-3-2 绘制系列点
如果我们想绘制系列点,可以将系列点的x轴值放在一个列表,y轴值放在另一个列表,然后将这2个列表作为参数放在scatter( )即可。
程序实例ch1_17.py:绘制系列点的应用。
执行结果
在程序设计时,有些系列点的坐标可能是由程序产生,其实应用方式是一样的。另外,可以在scatter( )内增加color(也可用c)参数,可以设定点的颜色。
程序实例ch1_18.py:绘制黄色的系列点,这个系列点有100个点,x轴的点由range(1,101)产生,相对应y轴的值则是x的平方值。
执行结果
上述程序第6行是直接指定色彩,也可以使用RGB(Red,Green,Blue)颜色模式设定色彩,RGB( )内每个参数数值是0~1。
1-3-3 设定绘图区间
可以使用axis( )设定绘图区间,语法格式如下:
axis([xmin, xmax, ymin, ymax]) # 分别代表x轴和y轴的最小和最大区间
程序实例ch1_19.py:设定绘图区间为[0,100,0,10000]的应用,读者可以将这个执行结果与ch1_18.py做比较。
执行结果
上述程序第5行是依据xpt列表产生ypt列表值的方式,由于网络上有很多文章使用数组方式产生图表列表,所以下一节笔者将对此做出说明,期待可为读者建立基础。
1-4 numpy模块
numpy是Python的一个扩充模块,可以支持多维度空间的数组与矩阵运算,本节笔者将对其最简单的产生数组的功能做解说,由此可以将这个功能扩充到数据图表的设计。使用前我们需导入numpy模块,如下所示:
import numpy as np
1-4-1 建立一个简单的数组linspace( )和arange( )
在numpy模块中最基本的就是linspace( )方法,使用它可以很方便地产生等距的数组,它的语法如下:
linspace(start, end, num)
start是起始值,end是结束值,num是设定产生多少个等距点的数组值,num的默认值是50。
在网络上阅读他人使用Python设计的图表时,常看到的产生数组的方法是arange( )。其语法如下:
start是起始值,如果省略默认值是0。stop是结束值,但是所产生的数组不包含此值。step是数组相邻元素的间距,如果省略默认值是1。
程序实例ch1_20.py:建立0, 1, …, 9, 10的数组。
执行结果
1-4-2 绘制波形
中学数学中我们有学过sin( )和cos( )概念,其实有了数组数据,我们可以很方便地绘制正弦和余弦的波形变化。单纯绘点可以使用scatter( )方法,此方法使用格式如下:
scatter(x, y, marker=‘.’, c(或color)=‘颜色’) # marker如果省略会 使用预设
程序实例ch1_21.py:绘制sin( )和cos( )的波形,在这个实例中调用plt.scatter( )方法2次,相当于也可以绘制2次波形图表。
执行结果
其实一般在绘制波形时,最常用的还是plot( )方法。
程序实例ch1_22.py:使用系统默认颜色,绘制不同波形的应用。
执行结果
1-4-3 建立不等宽度的散点图
在scatter( )方法中,(x,y)的数据可以是列表也可以是矩阵,预设所绘制点大小s的值是20,这个s可以是一个值也可以是一个数组数据,当它是一个数组数据时,利用更改数组值的大小,我们就可以建立不同大小的散点图。
在我们使用Python绘制散点图时,如果在两个点之间绘制了上百或上千个点,则可以产生绘制线条的视觉效果,如果每个点的大小不同,且依一定规律变化,则有特别的效果。
程序实例ch1_23.py:建立一个不等宽度的图形。
执行结果
1-4-4 填满区间
在绘制波形时,如要填满区间,此时可以使用matplotlib模块的f i ll_between( )方法,基本语法如下:
fill_between(x, y1, y2, color, alpha, options, … ) # options是其他参数
上述会填满所有相对x轴数列y1至y2的区间,如果不指定填满颜色,则会使用预设的线条颜色填满,通常填满颜色会用较淡的颜色,所以可以设定alpha参数将颜色调淡。
程序实例ch1_24.py:填满区间0~y,所使用的y轴值是函数式sin(3x)。
执行结果
程序实例ch1_25.py:填满区间-1~y,所使用的y轴值是函数式sin(3x)。
执行结果
1-4-5 色彩映射
至今我们针对一组数组或列表所绘制的图表皆是单色,以ch1_23.py第8行为例,色彩设定是color=(0,1,0),这是固定颜色的用法。在色彩的使用中,允许色彩随着数据而做变化,此时色彩的变化是根据所设定的色彩映射值(color mapping)而定,例如有一个色彩映射值是rainbow,内容如下:
在数组或列表中,数值低的值颜色在左边,会随数值变高往右边移动。当然在程序设计中,我们需要在scatter( )中增加color设定参数c,这时color的值就变成一个数组或列表。然后我们需要增加参数cmap(英文是color map),这个参数主要是指定使用哪一种色彩映射值。
程序实例ch1_26.py:色彩映射的应用。
执行结果
色彩映射也可以设定根据x轴的值做变化,或根据y轴的值做变化,整个效果是不一样的。
程序实例ch1_27.py:重新设计ch1_23.py,主要是设定固定点的宽度为50,将色彩改为依y轴值变化,同时使用hsv色彩映射表。
执行结果 如下方左图。
程序实例ch1_28.py:重新设计ch1_27.py,主要是将色彩改为依x轴值变化。
执行结果 如上右图。
目前matplotlib协会所提供的色彩映射内容如下:
序列色彩映射表
序列2色彩映射表
直觉一致的色彩映射表
发散式的色彩映射表
定性色彩映射表
杂项色彩映射表
在大数据研究应用中,可以将数据以图表显示,然后用色彩判断整个数据的趋势。在结束本节之前,笔者举一个使用colormap绘制数组数据的实例,这个程序会使用下列方法。
imshow(img, cmap=‘xx’)
参数img可以是图片,也可以数组数据,此例是数组数据。这个函数常用在机器学习检测神经网络的输出中。
程序实例ch1_29.py:绘制矩形数组数据。
执行结果
1-5 图表显示中文
matplotlib无法显示中文,主要在于安装此模块时所配置的下列文件:
~Python37\Lib\site-packages\matplotlib\mpl-data\matplotlibrc
在此文件内的font_sans-serif中没有配置中文字体,我们可以在此字段增加中文字体,但是笔者不鼓励更改系统内建文件。笔者将使用动态配置方式处理,让图表显示中文字体。其实可以在程序内增加下列程序代码,rcParams( )方法可以为matplotply配置中文字体参数,就可以显示中文了。
from pylab import mlp # matplotlib的子模块 mlp.rcParams[“font.sans-serif”] = [“SimHei”] # 黑体 mlp.rcParams[“axes.unicode_minus”] = False # 可以显示负号
另外,每个要显示的中文字符串需要在前面加上u。
程序实例ch1_30.py:重新设计ch1_13.py,以中文显示报表。
执行结果