数据可视化报告
- 第一回:数据展示初相识
- 生成画布 plt.figure()
- 保存画布 plt.savefig()
- 第二回:艺术图表见乾坤
- 绘制折线图 plt.plot()
- 绘制柱状图 plt.bar()
- 绘制饼图 plt.pie()
- Matplotlib 画廊
- 第三回:布局格式定方圆
- 坐标值 pd.Series()、pd.DataFrame()
- 轴刻度 plt.xticks()、plt.yticks()
- 轴标题 plt.xlabel()、plt.ylabel()
- 第四回:文字图例尽眉目
- 标题 plt.title()
- 图例 plt.legend()
- 数据标签 plt.text()
- 第五回:样式色彩秀芳华
- 图表的样式
- 数据标记点的样式
- 第六回:鸿雁在云鱼在水
- 关系图 seaborn.relplot()
- 分布图 seaborn.displot()
- 分类图 seaborn.catplot()
Python 做数据可视化时面临两大痛点:
- 绘图时现用现查,用过即忘,效率极低。
- 只会复制粘贴,不知其所以然,面对复杂图表一筹莫展。
我们介绍 Matplotlib 和 Seabron:
- 从图形,布局,文本,样式等多维度系统梳理 Matplotlib、Seabron 的绘图方法,构建对于绘图方法的整体理解。
- 从绘图 API 层级,接口等方面阐明 Matplotlib、Seabron 的设计理念,摆脱只会复制粘贴的尴尬处境。
Matplotlib 是一个 Python 2D 绘图库,在后面绘图的过程中并不是使用 Matplotlib 库本身,而是用 Matplotlib 库下面的一个模块 —— pyplot。
from matplotlib import pyplot as plt
# 导入 matplotlib 库下的 pyplot 模块并且将其简化为 plt
第一回:数据展示初相识
一张图是由画布、图表以及图表元素组成。
- 画布是整个图形的基础,画布的操作分成俩步 — 生成和保存。
- 图表是整个图形的核心内容,不同图表适合不同场景。
- 图表元素:图表标题、坐标轴刻度、坐标轴标题、图例和数据标签 — 其中,图表标题、坐标轴刻度、坐标轴标题是每张图都要具备的。当图中出现多个条件时,添加图例;当图中出现数值比较时,添加数据标签
读到这里,对数据可视化就有大致印象了。
依照代码实现逻辑,应该是先有画布,再有图表,具备这两者就能生成一张最简单的图,而要让这张图传递更丰富的信息,则需要添加图表元素。
生成画布 plt.figure()
# 生成画布,并设置画布的大小
plt.figure( figsize = (6, 6) )
生成画布用到的是 pyplot 模块下的 figure 函数,即 plt.figure()
。
其中的参数 figsize 可以控制画布的长和宽,一般用元组的形式进行赋值。
保存画布 plt.savefig()
生成的图形保存到本地,可以用 plt.savefig()
对画布进行保存,这里只需要设置它的路径参数。
plt.savefig('./xxx.png')
# 保存画布,并设置保存路径
第二回:艺术图表见乾坤
常见图表:
- 折线图:呈现数据变化趋势
- 柱状图:让数值大小的比较更明显
- 饼图:呈现各部分相对于整体的占比
绘制折线图 plt.plot()
绘制折线图用到 plt.plot()
函数,该函数中有两个参数 x 和 y 分别表示 x、y 坐标值。
直接将 x 和 y 坐标值传入 plt.plot()
函数,该函数就会自动将两个对象中的元素按照顺序匹配成坐标点,并绘制成折线图。
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 设置 x/y 坐标值
x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度'])
y = pd.Series([59, 70, 68, 56])
# 绘制折线图,并调整线条颜色为湖蓝色
plt.plot(x, y, color='dodgerblue')
绘制柱状图 plt.bar()
和折线图一样,绘制柱状图也需要设置(x,y)坐标值,不同的是柱状图绘图函数 plt.bar()的参数是 x 和 height,height 表示柱子的高,对应 y 坐标值。
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 设置坐标值
x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度'])
y = pd.Series([59, 70, 68, 56])
# 绘制柱状图,并调整颜色为深橘色,透明度为 60%
plt.bar(x, height=y, color='darkorange', alpha=0.6)
绘制饼图 plt.pie()
饼图和折线图、柱状图在图像特征方面差异蛮大的。
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 设置扇形面积值
x = pd.Series([59, 70, 68, 56])
# 设置百分比小数的位数:保留百分比小数点后两位
autopct='%.2f%%'
# 设置百分比字体大小和颜色
textprops = {'fontsize': 12, 'color': 'black'}
# 设置饼图的“爆炸效果”:让扇形远离圆心
explode = [0.1, 0, 0, 0]
# 设置不同扇形的颜色
colors = ['cornflowerblue', 'salmon', 'yellowgreen', 'orange']
# 绘制饼图
plt.pie(x, autopct=autopct, textprops=textprops,
explode=explode, colors=colors)
Matplotlib 画廊
Matplotlib 画廊:https://matplotlib.org/stable/gallery/index.html
Matplotlib 还有很多图表,上面的画廊相当于速查表,有成品的图表和代码实现。
第三回:布局格式定方圆
在绘制图表时,先确定好坐标点,再经由绘图函数就能生成图表。
坐标值 pd.Series()、pd.DataFrame()
# 设置 x/y 坐标值,Series 对象
x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度'])
y = pd.Series([160, 200, 180, 155])
# 设置 x/y 坐标值,DataFrame 对象
x = pd.DataFrame(['第一季度', '第二季度', '第三季度', '第四季度'])
y = pd.DataFrame([160, 200, 180, 155])
设置好坐标值后,就可以绘制图表。
假设绘制折线图 plt.plot()
,该函数中有两个参数 x 和 y 分别表示 x、y 坐标值。
plt.figure(figsize=(6, 6))
# 生成画布,并设置画布的大小
# 设置坐标值
x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度'])
y = pd.Series([59, 70, 68, 56])
# 绘制折线图,并调整线条颜色为湖蓝色
plt.plot(x, y, color='dodgerblue')
轴刻度 plt.xticks()、plt.yticks()
设置 x、y 轴刻度的函数分别是 plt.xticks()
和 plt.yticks()
。
# 设置坐标轴的刻度字体大小
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
轴标题 plt.xlabel()、plt.ylabel()
坐标轴标题主要对坐标轴刻度值的含义进行描述,设置 x 轴标题和 y 轴标题分别用到 plt.xlabel()
和 plt.ylabel()
函数。
# 设置坐标轴的标题名及字体大小
plt.xlabel('季度', fontsize=15)
plt.ylabel('研发费用(百万元)', fontsize=15)
第四回:文字图例尽眉目
看文章先从标题看起,看图同样也从标题看起。
标题 plt.title()
图表标题默认放在图表顶部,向读者传递图表的名称。设置图表标题用的是 plt.title()
函数,包含两个参数:
- label:标题名
- fontsize:标题的字体大小
plt.title('男女比例图', fontsize=20)
# 设置图表标题名及字体大小
图例 plt.legend()
设置图例用到 plt.legend()函数,其中的参数labels表示图例名称,对应图中的多个条件,通常传入可迭代对象,比如列表、Series 对象等。
plt.legend(['变化', '分布'])
数据标签 plt.text()
数据标签是指坐标点上方显示的标签,用于呈现每个坐标点的数据信息。
添加数据标签用到 plt.text()函数,它有几个参数,分别是 x、y、s、ha、va 以及 fontsize。
# 设置数据标签
plt.text('第一季度', 160, 160, ha='center', va='bottom', fontsize=12)
plt.text('第二季度', 200, 200, ha='center', va='bottom', fontsize=12)
plt.text('第三季度', 180, 180, ha='center', va='bottom', fontsize=12)
plt.text('第四季度', 155, 155, ha='center', va='bottom', fontsize=12)
更通用的是,借助 zip()
函数实现。
# 设置数据标签
for a, b in zip(x, y):
plt.text(a, b, b, ha='center', va='bottom', fontsize=12)
第五回:样式色彩秀芳华
图表的样式
任何一个绘图函数都有很多参数,如折线图函数 plt.plot()
坐标值(x,y)是最少必备参数,如果我们想让图表展示的图表效果更惊艳,就也得学习一下后面的参数。
先看线条的宽度和颜色:
- linewidth 可以设置线条的宽度
- color 可以设置线条的的颜色,传入颜色对应的英文单词
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 绘制折线图,只调整线条的样式,颜色是 red,简写为 r
plt.plot(x, y, linewidth=3, color='r')
线条宽度变宽,并且变成红色。
数据标记点的样式
以上是图表(线条)样式,另一个是数据标记点样式,需要用到的参数是 marker、markerfacecolor 和 markersize。
- marker:设置数据标记点的形状
- markersize:设置数据标记点的大小
- markerfacecolor:填充颜色
我们选择数据标记点的形状为圆(marker=‘o’);大小为 10(markersize=10);填充颜色为白色(markerfacecolor=‘w’)。
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 绘制折线图,只调整数据标记点的样式
plt.plot(x, y, linewidth=3, color='r', marker='o',
markersize=10, markerfacecolor='w')
第六回:鸿雁在云鱼在水
我们研究的数据,都分成定性和定量俩类。
- 定性:又叫分类数据,如性别、游戏段位
- 定量:可用数字量化的数据,如身高体重
对于定性数据,我们常常需要分析不同类别的信息,例如分析《王者荣耀》中最强王者的男女比例等。
至于定量数据,我们比较感兴趣的是不同变量之间的关系或者变量的分布情况,比如身高和基因的关系、某品牌手机销售额的分布情况等。
在统计学中,我们把用来描绘数据基本情况的统计学方法称为描述性统计。
再将数据映射到坐标系上时,就会得到我们常说的统计图形。
而用于表现数据的关系、分布或者分类情况的,可以被称为描述性统计图形。
Seaborn 的图形分类也参考了上述概念,描述性统计图形有关系图、分布图、分类图这三类。
分别用于对应不同的数据类型和分析目的:
- 关系图:展示定量数据之间关系的趋势,如离散程度或者数据随时间变化的情况。
- 分布图:展示定量数据的分布信息,比如频数分布情况,数据的形态等。
- 分类图:展示定性数据之间的分布或关系之类的信息,比如不同类别数据的大小,分布情况等。
有这个框架在,描述性统计图形就一通百通了。
- 关系图:散点图、折线图,定量数据之间关系的趋势。
- 分布图:直方图、核密度估计图、经验累积分布图、轴须图,定量数据的分布信息。
- 分类图:箱型图、分布散点图、分簇散点图、增强箱型图、小提琴图、点图、计数图、条形图,定性数据之间的分布或关系之类的信息。
关系图 seaborn.relplot()
散点图又叫 X-Y 图,将所有的连续数据以点的形式展现在坐标系上。
可比较直观地观察变量 x 与变量 y 之间的相关性。
适合变量之间存在密切关系,但是这些关系又不像数学或物理公式那样能够精确表达的。
- 无关 :在散点图中,如果变量之间不存在线性关系,则表现为随机分布的离散的点。
- 正相关 :当变量 x 增大的时候,变量 y 也在增大;变量 x 减小的时候,y 也在减小。
- 负相关 :当变量 x 增大的时候,y 减小;当 x 减小的时候,y 增大。
在观察散点图的时候,还有一个概念需要我们理解 —— 离群点。
当变量间存在某种线性关系时,大部分的数据点会表现出 “报团取暖”,相对密集的形态,但总有几个不合群的,“高冷” 的数据点离集群较远,我们可以称这些点为离群点或异常点。
观察散点图步骤:
- X、Y 轴代表哪俩个变量
- 相关关系,是否有线性关系
- 离群点,有木有特殊意义
散点图函数:seaborn.relplot(x, y, data, hue, size, style, kind)
import pandas as pd
student_info = pd.read_csv('./学生信息.csv')
# 先把数据通过 pandas 读取成 DataFrame 类型后再传给 relplot 参数 data
import seaborn as sns
sns.relplot(x='身高', y='体重', data=student_info, kind=scatter)
# data 是数据集,x、y 是数据集里面的连续数据
# kind 是关系图的类别,scatter 是散点图,line 是折线图,其实 kind 默认是散点图
可以看到,大部分数据点都比较集中,且身高越高,相应的体重也会越大,身高和体重应该是正相关关系。
student_info 数据集其实数据还有分类(男、女),我们可以分开显示。
sns.relplot(x='身高', y='体重', data=student_info, hue='性别')
# hue 可让图中添加一个维度,通过图中的不同颜色表示不同含义
男生和女生用不同的颜色标记了出来。从整体上看,该数据集中的男生身高还是普遍高于女生的。
我们还可以让数据展示的更显著,参数 size 可以让表示体重的点,随体重增大而增大。
sns.relplot(x='身高', y='体重', data=student_info, hue='性别', size=1)
# 1 代表第 2 个参数,即体重
我们发现,学生数据的分类,不仅有性别,还有班级。
sns.relplot(x='身高', y='体重', data=student_info, hue='性别', size='体重', style='班级')
使用 style = 班级
,这样不同班级点的不同形状区分数据,1班是圆、2班是方形。
关系图,除了散点图,还有折线图。
折线图也可以反映数据间的关系,只不过它一般使用时间维度作为 X 轴,数值维度作为 Y 轴。
当我们想要了解某一维度在时间上的规律或者趋势时,用折线图是个比较不错的选择。
relplot() 函数也是可以画出折线图的,基本的折线图只需要在必选参数的基础上,只要写成 kind=‘line’ 即可。
折线图函数:sns.relplot(x, y, data, kind=‘line’)
这也是 Seaborn 的一大优势,想要画某一大类下面的不同图形时,只需要调用这一大类的函数,少量修改其中的参数即可。
分布图 seaborn.displot()
根据 Seaborn 的划分,Distribution 类别中共有四种图形:直方图、核密度估计图、经验累积分布图和轴须图,它们都可以用来表示定量数据的分布情况。
P.S. 人的眼睛对颜色比对形状更敏感,因此,在做可视化时,我们可以优先考虑使用颜色来区分不同的数据。
直方图是描述性统计中很常见的一种图形,它牵涉到统计学中的频数这一概念。
频数,又称 “次数”。指变量值中代表某种特征的数值出现的次数。
在直方图中,我们会把连续数据进行分组,而后统计每个分组内数据的数量(即频数),接着,在平面直角坐标系中用 X 轴标记出每个分组的端点,用 Y 轴表示频数,这样,在坐标系中生成的每个矩形的高就代表了对应分组的频数。
如果从形状来看的话,直方图与柱状图会非常类似。
虽然相似,但从上面的对比图中也可以看出,柱状图的方块之间有间隔,然而直方图各个方块之间没有间隔,紧密相连(当然也有例外情况。在某个分布数据的频数极少或没有时,会出现断点,比如上图直方图中的最右侧方块)。
但它们两个最大的区别还是在数据类型上,柱状图用于画出定性数据(分类数据)的某些特征,直方图则是用于展示定量数据的分布情况。
我们还可以通过直方图来观察数据分布的大体形状,比如:数据分布是否对称,是右偏还是左偏等。
如果数据分布大体对称的话,图形会呈现出中间高,两边低,左右近似对称的特点,就像上图中间所示形状一样。
如果数据的 众数 < 中位数 < 平均数
,那么分布大体就会呈现出右偏分布的情况,形状上类似上图左侧部分。
如果数据的 众数 > 中位数 > 平均数
,那么分布大体就会呈现出左偏分布的情况,形状上类似上图右侧部分。
画直方图的函数:sns.displot(x, data, hue, kind=‘hist’) 。
这里,借用一下泰坦尼克号乘客的数据。
# 将'乘客性别'赋值给参数 hue
sns.displot(x='乘客年龄', data=titanic_info, hue='乘客性别', kind='hist')
根据图形显示,蓝色代表男性,橙色代表女性,图形中的灰色部分是颜色重合造成的。总体来看,男乘客的数量是要高于女乘客的,尤其是在青壮年(20 岁-40 岁)群体中,这一差异非常明显。
直方图一般用来统计连续数据分组后,每个组对应的频数,可以从形状上判断数据分布的大体形状,比如:数据分布是否对称,是右偏还是左偏等。
核密度估计图:sns.displot(kind=‘kde’)
经验累积分布图:sns.displot(kind=‘ecdf’)
分类图 seaborn.catplot()
Seaborn 给 Categorical(分类)中安排了八种图:分布散点图、分簇散点图、箱型图、增强箱型图、小提琴图、点图、条形图和计数图,他们都可以用来表示定性数据中不同类别之间的关系。
箱型图又称盒须图、盒式图或箱线图,它可以反映一组数据的分布特点,如分布是否对称,是否存在异常值,但其更适合对多组数据(分类数据)的分布特征进行比较。
当一个数据集同时包含分类变量和连续变量时,箱形图可以提供连续变量随着分类变量改变而变化的信息。
它使用了 5 个关键数值对分布进行概括,即一组数据的上相邻值、下相邻值、第一四分位数、中位数和第三四分位数。至于数据集中的异常值,则会被绘制成单独的点。
当我们把一组数据按照从大到小的顺序排序后,需要关注几个特殊的数据:第一四分位数(Q1)、中位数(Median)和第三四分位数(Q3),即处在 25%、50% 和 75% 位置上的数据。箱子的上下边框,就是第三四分位数(Q3)和第一四分位数(Q1)。
Q3 与 Q1 的差称为四分位差或四分位距,用 IQR 表示。
我们可以根据 IQR 来计算出上下内围栏的范围,内围栏(inter fence)是指与 Q1 和 Q3 的距离等于1.5 倍 IQR 的两个点,其中Q1 - 1.5IQR 为下内围栏,Q3 + 1.5IQR 为上内围栏。
上下内围栏一般不在箱线图中显示,但它们明确了数据的范围,在上下内围栏以外的数据,都是异常值。
去掉异常值后,找出上下内围栏之间的最大值和最小值,也就是图中所示的上相邻值和下相邻值。
通过观察箱型图,我们可以直观地了解到中位数,上相邻值和下相邻值这几个描述数据分布情况的关键值,也可以清晰地看到数据集中是否存在异常值。
如上图所示,假如中位数在箱子中间位置的话,就说明这些数据是对称分布的;箱子的长短也能体现分布情况,箱子较长意味着分布比较分散,若箱子很短,则数据分布得较为集中。
箱型图函数:sns.catplot(x, y, data, hue, order, kind=‘box’)
# 使用 sns.catplot(),横轴为类型,纵轴为价格
sns.catplot(x = '价格', y = '类型', kind='box', data=chart_df)
在生成的图片中,配饰和鞋子的中位数较高,食品的中位数最低,一定程度上说明配饰和鞋子的花费较高,食品的花费最低。看得出来,在如何变美这件事上花的钱要比吃饭多出不少。
比较长的箱子是配饰,说明配饰的价格数据比较分散,原因可能是在买普通饰品的同时也买过较贵的高端饰品。
衣服、配饰和鞋子的中位数都近似在箱子的中间位置,看来这三类的价格分布较为对称。
我们还能在图片中发现,衣服、日用品和食品的价格中都存在离群点,衣服类型中有两个,日用品和食品类型各一个。
kind 的其他值还可以是:
- ‘strip’ 对应的分布散点图
- ‘swarm’ 对应的分簇散点图
- ‘violin’ 对应的小提琴图
- ‘boxen’ 对应的增强箱型图
- ‘point’ 对应的点图
- ‘bar’ 对应的条形图
- ‘count’ 对应的计数图
最后,安利一款 Visual Python 软件(Python 图形化软件),不需要敲代码,直接操作可视化界面,随意 DIY 这个窗口,软件会自动生成 DIY 后的界面代码,欢迎试用~