学习目标
了解数据可视化概念
掌握图表中相关的术语
了解绘制图表的相关函数
掌握绘制散点图
掌握绘制折线图
掌握绘制条形图
掌握绘制直方图
掌握绘制面积图
掌握绘制饼图
掌握绘制子图
掌握图中的中文显示
掌握组合图形与标注
掌握保存图片
数据可视化基础
数据可视化是一个新术语,它不仅通过图表展示数据,更使用直观的方式将数据背后的信息展示出俩。相对于大量的原始数据,人类可以快速理解数据可视化后的图表表达的信息。
目前成熟的图表已超过30种,每种图表有特定的实用场景和特点。
数据有多种展示的方式,不同的展示方式突出的重点不同。
下面是常用的几种图表:
图表类型 | 使用场景 | 例子 |
---|---|---|
折线图 | 展示数据随时间或有序类别的波动情况的趋势变化 | - 某学生最近30天每日步行数 - 股价每日收盘价 |
直方图 | 分布分析展示数值在区间范围内的分布,可反映分类项目之间的比较,也可以用来反映时间趋势 | 比较同一个班级的学生在家庭作业、期中考试、期末考试和全部课程成绩的得分分布 |
散点图 | 研究不同变量间的关系 | - 男性与女性人群中不同年龄阶段得皮肤病的可能性 - IQ测试得分和学习成绩之间的相关性 |
饼图 | 在一个空间或图上展示比例,展示不同部分所占百分比 | - 调查中的相应分类 - 一种特定技术的前五家公司的市场份额 |
气泡图 | 用于展示三个变量之间的关系,横纵中表示其中两个变量,第三个变量用气泡的大小表示 | 对比多种磁盘的性能,价格和销量。x轴表示价格,y轴表示性能,气泡大小表示销量 |
核密度估计图 | 估计概率密度函数(非参数检验方法) | 股票、金融等风险预测 |
树状图 | 与组织结构有关的分析,即有明确的层次关系的数据 | 展示企业组织结构 |
小提琴图 | 展示数值在区间范围内的分布 | 不同性别对应的消费额 |
选择正确的图表和绘制技巧需要大量的练习和对比。有效的数据可视化有助于理解数据或传递信息。数据可视化的过程也需要对数据进行分析和提取,通过对数据的分析展现出其统计信息或隐藏的信息。
数据可视化是数据分析后的一个过程,但是通常数据分析和数据可视化过程常常是交互进行的。
数据可视化的主要原则是根据目标读者的需求,结合通过分析数据能展示的问题,采用能精确呈现数据的特征的图表进行可视化。
应用统计图表的目的是能够准确、直观地反映一组数据所蕴含的信息,帮助人们迅速地解读数据。对于同一组数据,有时可以画出不同的统计图,但不是任何一种统计图都能准确而只管地反映数据所表达信息,因此要根据调查的目的和数据的特点选择适当的统计图。
数据本身并不能确定图表类型,更重要的是通过数据表达的观点。选择图表类型有一定的技巧和原则,但是对于特定问题需要独立分析。美国专家Andrew Abela整理的一张图表类型选择指南。他根据需要表达的主题将图分为比较、分布、构成、联系四类。在每种类别下,根据不同情况选择不同的图表进行展示。
同样的数据,站在不同的立场上去解析,不同人发现的信息和观点可能不一样。不仅选用的图表类型不一样,即使采用同样的图表类型,通过不同的数据展示方式也可以强调不同观点。最重要的是,这种方法具有很强的迷惑性。
例如:某公司有5个股东,100个职工,公司的股东利润和员工工资总额如表所示:
年份 | 2016年 | 2017年 | 2018年 |
---|---|---|---|
职工工资(万元) | 200 | 220 | 250 |
股东利润(万元) | 100 | 120 | 150 |
公司股东、工会和职工代表用同样的数据绘制了三张不同的图表。
从上面例子可以看出,从同样数据画出的三份图表,得出了三种不同的结论。股东、工会、职工三者是根据同一组数据从各自不同的观点出发,绘制出不同的统计图,进而根据它们得出了要表达的不同含义。应该说,三者都是有理有据的。同一组数据,不同的人站在不同的角度,可以画出不同的统计图,进而可以得出不同的结论。
图表展示的观点差异主要取决于几个方面:
- 要表达的观点和突出的重点;
- 从数据中提取的信息;
- 数据间的关系及提供信息的方法。
数据本身对图表的选择和设计也有一定的影响。如采用直方图表示数据对比,当数据项差异悬殊时可能某些数据项数值过小无法得到量化的结果。如数据分类不当,饼图也无法传递有效的信息。这些情况都要对图表进行进一步的处理和美化。
使用Matplotlib绘图
Python语言的matplotlib扩展包是一个提供了跨平台的2D图形库,它可以将数据用多重形式展示出来。Matplotlib可以画出折线图、柱状图、饼图、雷达图等。在matplotlib的官网上给出了500多个图表展示的例子程序(https://matplotlib.org/gallery/index.html)。
Matplotlib提供了详细的在线API文档(https://matplotlib.org/api/),并且在每个函数介绍后提供了使用该函数的例子。
Matplotlib提供了两种编程风格,一种是函数式绘图,这种方式参考了matlab里面的绘图函数语法。另一种是面向对象式绘图,这种方式更接近Matplotlib的底层架构,更能理解细节。
matplotlib.pyplot是一个函数式绘图的函数集合,其中每一个pyplot的函数都对图进行一些改动,例如创建图,画点或线,以及增加标签等。
在面向对象方式中,matplotlib.axes.Axes和matplotlib.figure.Figure是最主要的两个对象,分别表示坐标轴和图。这种模式下,通常使用pyplot.subplots创建一个图和多个坐标轴,并在此基础上调用相关对象的方法绘制图。
Matplotlib模块依赖于Numpy和tkinter模块,可以绘制多种形式的图形,包括线图、直方图、饼图、散点图等,图形质量满足出版要求,是数据可视化的重要工具。Matplotlib中应用最广的是matplotlib.pyplot模块。pyplot提供了一套和Matlab类似的绘图API,使得Matplotlib的机制更像Matlab。我们只需要调用pyplot模块所提供的函数就可以实现快速绘图并设置图表的各个细节。
使用matplotlib时,使用的导入惯例为:import matplotlib.pyplot as plt
想象你在一张纸上作图,所做的图是图表,用到的纸是画布,对图表进行解释的内容是图表元素。
依照代码实现逻辑,应该是先有画布,再有图表,具备这两者就能生成一张最简单的图,而要让这张图传递更丰富的信息,则需要添加图表元素。
图表相关的术语:
- 图表区:表示整个图表,包含所有数据系列、坐标轴、标题、图例、数据表等。绘图区是图表的一部分,由垂直坐标轴和水平坐标轴及其负轴包围的区域。
下图给出了图表中的常用术语:
- 标题(Title)和图例(Legend):图表标题用于对图表的功能进行说明,通常出现在图表区的顶端中心处。图例是一个方框,用于标识为图表中每个数据系列或分类指定的图案或颜色。默认情况下,图例放在图表的右侧。
- 数据标签:是指派给单个数据点的数值或名称。它在图表上的显示是可选的。数据标签可以包含很多项目。如“系列名称”、“类别名称”、“值”、“百分比”和“气泡尺寸”。text函数可以在图表区任意位置显示文字。
- 坐标轴(Axes):一般情况下,图表有两个用于对数据进行分类和度量的坐标轴:分类轴和数值轴。三维图表有三个轴。饼图或圆环图没有坐标轴。某些组合图表一般还会有次分类轴和次数值轴。次数值轴出现在主数值轴绘图区的反面,它在绘制混合类型的数据(如数量和价格),需要各种不同刻度时使用。一般情况下,主数值轴在绘图区的左侧,而次数值轴在绘图区的右侧(对于条形图,主数值轴在绘图区的下部,而次数值轴在绘图区的上部)。坐标轴包括坐标刻度线(tick)、刻度线标签(tick label)和轴标题(label)等。刻度线是类似于直尺分割线的短度量线,与坐标轴相交。刻度线标签用于标识坐标轴的分类或值。轴标题是用于对坐标轴进行说明的文字。
- 数据:数据在绘图区通过不同的函数可以表现为线(plot)、柱状图(bar)、散点(scatter)等。绘制折线图时,每条折线就是一个数据系列,对应的y值是一个列表,和x的列表大小一致。图表中的数据序列可以指定颜色或图案,并展示在图表的图例中。折线图,散点图可以有一个或多个数据序列。但是饼图只有一个数据序列。
- 网格线(Grid)和趋势线:网格线是添加到图表中易于查看和计算数据的线条,是坐标轴上刻度线的延伸,并穿过绘图区。有了网格线,就很容易回到坐标轴进行过程也称为回归分析。Matplotlib中没有趋势线的概念,可参照。趋势线以图形方式说明数据系列的变化趋势。它们常用于绘制预报图表,这个预报以通过numpy,scikit-learn等第三方库计算出趋势,并用plot函数用不同颜色或标记叠加在真实数据上。
matplotlib可绘制不同的图表,下面以一个简单的正弦函数为例说明图表的绘制方法。
'''
程序首先准备了x,y两个数组,x是0~720度,y是对应的正弦函数值。使用axis函数设定x,y坐标轴的起止范围,plot函数画出正弦曲线,xticks指定x轴的小刻度标示。xlabel和ylabel分别是x,y轴的主题,title设置了图表的主题。
'''
import matplotlib.pyplot as plt
import math
x = range(721)
y = [math.sin(i * 3.14 / 180) for i in x]
plt.axis([0, 720, -1.1, 1.1])
plt.plot(x, y, 'b')
plt.xticks(range(0, 721, 90))
plt.xlabel('degree')
plt.ylabel('sin')
plt.title('sin function')
plt.show()
函数简介
函数 | 说明 |
---|---|
figure() | 创建一个新的绘图窗口 |
figtext() | 为figure添加文字 |
axes() | 为当前figure添加一个坐标轴 |
plot() | 绘图函数 |
polar() | 绘制极坐标图 |
axis() | 获取或设置轴属性的边界方法(坐标的取值范围) |
clf | 清除当前figure窗口 |
cla | 清除当前axes窗口 |
close | 关闭当前figure窗口 |
subplot | 一个图中包含多个axes |
text() | 在轴上添加文字 |
title() | 设置当前axes标题 |
xlabel/ylabel | 设置当前X轴或Y轴的标签 |
hist() | 绘制直方图 |
hist2d() | 绘制二维直方图 |
hold | 设置当前图窗状态;off或者on |
imread() | 读取一个图像,从图形文件中提取数组 |
legend() | 为当前axes放置标签 |
pie() | 绘制饼状图 |
scatter() | 做一个X和Y的散点图,其中X和Y是相同长度的序列对象 |
stackplot() | 绘制一个堆叠面积图 |
acorr() | 绘制X的自相关函数 |
annotate() | 用箭头在指定的数据点创建一个注释或一段文本 |
bar() | 绘制垂直条形图 |
barh() | 绘制横向条形图 |
barbs() | 绘制一个倒钩的二维场 |
图表类型及相关函数
图表类型 | 函数 | 备注 |
---|---|---|
折线图 | plot(x, y, format_string, **kwargs) | 二维线画图函数,可以绘制折线图和散点图 |
柱状图 | bar(x, height, width, , align = ‘center’, *kwargs) | 绘制柱状图,该函数可以多次调用,有叠加效果 |
散点图 | scatter(x, y) | 创建一个包含圆形的散点图,x,y是长度相同数组 |
饼图 | pie() | 绘制饼状图,可以自己计算每个类别所占的比例 |
直方图 | hist() | 输入一个序列,并指定分为几个区间进行统计 |
面积图 | stackplot(x, args, *kargs) | 绘制面积图,图像形如在不同折线间填充了颜色 |
坐标轴格及相关函数
坐标轴格式 | 函数 | 备注 |
---|---|---|
X轴标题 | xlabel() | 设置图片中X轴的标签信息 |
X轴刻度线 | xticks(x_tick, xtick_label, fontproperties, fontsize) | 设置X轴的刻度信息(允许使用文本作为刻度值) |
X轴坐标起止范围 | xlim(xmin, xmax) | 设置X轴坐标的起止范围 |
Y轴标题 | ylabel() | 设置图片中Y轴的标签信息 |
Y轴刻度线 | yticks() | 设置Y轴的刻度信息(允许使用文本作为刻度值) |
Y轴坐标起止范围 | ylim(ymin, ymax) | 设置Y轴坐标的起止范围 |
坐标起止范围 | axis([xmin xmax ymin ymax]) | 绘图中用于设置坐标值范围 |
标注类型及相关函数
标注类型 | 函数 | 备注 |
---|---|---|
图表标题 | title() | 设置整个数据图的标题 |
图例 | legend(args, *kwargs) | 添加图例 |
数据标签 | text(x, y, s) | 可以在绘制的图片任何地方添加描述信息 |
箭头 | arrow() | 绘制一条带箭头的直线 |
其他一些功能
功能 | 函数 | 备注 |
---|---|---|
隐藏图表 | hide() | 隐藏图表 |
显示图表 | show() | 将图形呈现出来 |
增加子图 | add_subplot(args, *kwargs) | 增加子图 |
创建多个子图 | subplots(3, 1, 1) | 该函数的第一个参数是子图的行数,第二个参数是子图的列数,第三个参数是一个从1开始的序号 |
散点图
散点图由一些不连续的点组成,用来研究两个变量的相关性。包括正相关、负相关、不相关。主要通过scatter函数画散点图。
格式:def scatter(x, y, s = None, marker = None, cmap = None, morm = None, vmin = None, vmax = None, alpha = None, linewidths = None, verts = None, edgecolors = None, hold = None, data = None, **kwargs):
说明:
- x/y:数据,都是向量,而且必须长度相等
- s:标记大小,以像素点的平方为单位的标记面积,指定为一下形式之一:
- 数值标量:以相同的大小绘制所有标记
- 行或列向量:使每个标记具有不同的大小。x、y和sz向量中的相应元素确定每个标记的位置和面积。sz向量的长度必须等于x和y的长度
- 默认大小为rcParams[‘lines.markersize’]**2
- c:标记颜色,指定为下列形式之一:
- RGB三元数或颜色名称-使用相同的颜色绘制所有标记
- 由RGB三元数组成的三列矩阵-对每个标记使用不同的颜色。矩阵的每行为对应标记指定一种RGB三元数颜色。行数必须等于x和y的长度
- 向量-对每个标记使用不同的颜色,并以线性方式将c中的值映射到当前颜色图种的颜色。c的长度必须等于x和y的长度。要更改坐标区的颜色图,需使用colormap函数。在绘制散点图时,如果希望散点颜色成为颜色图的索引,可以使用RGB颜色对照表中色值代码的形式指定c
颜色对照表
选项 | 说明 | 对应的RGB色值代码 |
---|---|---|
‘red’或’r’ | 红色 | #FF0000 |
‘green’或’g’ | 绿色 | #00FF00 |
‘blue’或’h’ | 蓝色 | #0000FF |
‘yellow’或’y’ | 黄色 | #FFFF00 |
‘magenta’或’m’ | 品红色 | #FF00FF |
‘cyan’或’c’ | 青蓝色 | #00FFFF |
‘white’或’w’ | 白色 | #FFFFFF |
‘black’或’b’ | 黑色 | #000000 |
注意:在绘制散点图时,如果要使用非预定义颜色绘制点,也可以使用RGB颜色对照表中色值代码的形式来指定颜色,形如
c = ['#FFDAB9', '#FF1493', '#E066F']
,该方法可以指定任意颜色。使用时要注意c中参数个数与x,y个数相等。
marker:标记样式,其中值和说明如表所示 | 值 | 说明 | | —- | —- | | ‘o’ | 圆圈 | | ‘+’ | 加号 | | ‘*’ | 星号 | | ‘.’ | 点 | | ‘x’ | 叉号 | | ‘square’或’s’ | 方形 | | ‘diamond’或’d’ | 菱形 | | ‘^’ | 上三角 |
edgecolors:轮廓颜色,和c类似,参数也相同
- alpha:透明度,[0, 1]:1不透明,0透明
- cmap:色彩盘,可以使用默认的也可以使用自定义的,它实际上就是一个三列的矩阵(或者说,shape为[N, 3]的array),矩阵中的值取值范围为[0., 1.],每一行代表一个颜色(RGB)
- linewidths:线宽,标记边缘的宽度,默认是没有外围轮廓线,color、marker等不能同时作为一个参数,plt.scatter(x1, y1, ‘bo’, s = 5)不合法
比如现在有一组女大学生的身高和体重数据,可以画散点图来观察两组数据之间的关系。
编号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
身高(cm) | 152 | 158 | 167 | 172 | 162 | 166 | 180 | 177 | 172 | 172 | 156 | 164 |
体重(kg) | 51 | 46 | 55 | 60 | 55 | 56 | 65 | 66 | 68 | 60 | 56 | 55 |