目录
在实际工作中, 我们不能过分依赖相关系数, 为什么这么说呢?因为统计指标是有局限性的。我们做数据清理的时候, 就规避了离群值对统计的影响, 并且, 在机器学习, 深入学习高速发展的大环境里, 用方差, 平均数来描述数据维度是远远不够的。
1973年, 统计学家Francis Anscombe , 在《The American Statistician》杂志上发了一篇论文, “Graphs in Statistical Analysis”, 统计分析中的图形, 意欲说明统计数值(均值, 方差, 相关系数)有时具有欺骗性, 拿到一组数据, 首先还是要作图, 图形很重要, 因为离群值或者异常值对一些统计值(均值, 方差)的影响太大了。
这组被后人称之为Anscombe’s Quartet (安斯库姆.四重奏)的数据, 输入EXCEL, 并用EXCEL函数计算均值、标准差、方差、相关系数r, 斜率和截距, 可以看出四组数据的这些统计值几乎完全一致。
绘制四组数据的散点图, 观测数据分布情况, 同时做线性回归的拟合曲线, 如下图所示:
像图#4为一条垂直线和一个异常值。图#4这种根本就不适合用线性回归来模拟, 数据分布是否线性是采纳线性回归的重要前提之一。
安斯库姆四重奏不仅是提示线性回归前统计图辅助观察判断额重要性, 几乎所有统计分析/数据分析都适用的。在分析数据之前, 描绘数据所对应的可视化图形有多么的重要!
1. matplotlib
matplotlib, 是matrix + plot + library的缩写, 最初人们创建它是为了仿效 MATLAB 的绘图功能, 现在它自己已经发展成为特性完善的库了, 并拥有超多的功能。
import matplotlib.pyplot as plt
#将风格设置为近似 R 中的 ggplot 库
plt.style.use('ggplot')
# 设置插图, 让它们在记事本中可见
%matplotlib inline
调用matplotlib库绘图一般是用pyplot子模块, 其集成了绝大部分常用方法接口, 查看pyplot源码文件可以发现, 它内部调用了matplotlib路径下的大部分子模块(不是全部), 共同完成各种丰富的绘图功能。其中有两个需要重点指出:figure和axes, 其中前者为所有绘图操作定义了顶层类对象Figure, 相当于是提供了画板;而后者则定义了画板中的每一个绘图对象Axes, 相当于画板内的各个子图。换句话说, figure是axes的父容器, 而axes是figure的内部元素, 而我们常用的各种图表、图例、坐标轴等则又是axes的内部元素。
当然, 之所以不能称pyplot为一级命名空间的原因, 不仅仅在于它在形式上隶属于matplotlib, 最主要的在于它还不算是matplotlib的"独裁者", 因为matplotlib的另一个重要模块——pylab——或许称得上是真正意义上的集大成者:pylab被定位是python中对MATLAB的替代产品, 也就是说凡是MATLAB可以实现的功能, pylab通通都要有, 例如矩阵运算(包括常规矩阵运算、线性代数、随机数、FFT等)、绘图功能等等。
用matplotlib绘制可视化图表, 主要有3种接口形式:
- plt接口, 例如常用的plt.plot(), 用官方文档的原话, 它是matplotlib的一个state-based交互接口, 相关操作不面向特定的实例对象, 而是面向"当前"图
- 面向对象接口, 这里的面向对象主要是指Figure和Axes两类对象。前文提到, Figure提供了容纳多个Axes的画板, 而Axes则是所有图标数据、图例配置等绘图形元素的容器。面向对象的绘图, 就是通过调用Figure或Axes两类实例的方法完成绘图的过程(当然, Figure和Axes发挥的作用是不同的)。通俗的说, 就是将plt中的图形赋值给一个Figure或Axes实例, 方便后续调用操作
- pylab接口, 如前所述, 其引入了numpy和pyplot的所有接口, 自然也可用于绘制图表, 仍然可看做是pyplot接口形式。因其过于庞大官方不建议使用
1.1 常用图表形式
- plot: 折线图或点图, 实际是调用了line模块下的Line2D图表接口
- scatter: 散点图, 常用于表述两组数据间的分布关系, 也可由特殊形式下的plot实现
- bar/barh: 条形图或柱状图, 常用于表达一组离散数据的大小关系, 比如一年内每个月的销售额数据;默认竖直条形图, 可选barh绘制水平条形图
- hist: 直方图, 形式上与条形图很像, 但表达意义却完全不同:直方图用于统计一组连续数据的分区间分布情况, 比如有1000个正态分布的随机抽样, 那么其直方图应该是大致满足钟型分布;条形图主要是适用于一组离散标签下的数量对比
- pie: 饼图, 主要用于表达构成或比例关系, 一般适用于少量对比
- imshow: 显示图像, 根据像素点数据完成绘图并显示
1.2 图例元素
- title: 设置图表标题
- axis/xlim/ylim: 设置相应坐标轴范围, 其中axis是对后xlim和ylim的集成, 接受4个参数分别作为x和y轴的范围参数
- grid: 添加图表网格线
- legend: 在图表中添加label图例参数后, 通过legend进行显示
- xlabel/ylabel: 分别用于设置x、y轴标题
- xticks/yticks: 分别用于自定义坐标轴刻度显示
- text/arrow/annotation: 分别在图例指定位置添加文字、箭头和标记, 一般很少用
1.3 自定义配置
matplotlib提供了自定义参数实现批量配置——rcParams, 全称(runtime configuration Parameters), 即运行时配置参数。顾名思义, 就是在python程序运行时临时执行的配置参数。rcParams是一个字典格式, 当前共有299个键值对, 分别对应一组参数配置选项。其中用得最多的可能是通过设置字体和减号编码来解决乱码的问题, 但实际上它的功能强大之处可远非如此。
另一个简单易用的自定义配置选项是style, 即设置绘图风格, 最早在matplotlib1.4版本中引入, 当前共支持26种绘图风格, 这里的绘图风格类似于很多IDE支持不同主题。可以通过plt.style.available命令查看, 返回一个可选风格的列表。
1.4 走向3D
在可视化愈发重要的当下, matplotlib当然不仅支持简单的2D图表绘制, 其也提供了对3D绘图的丰富接口。contour, 实际上是一个伪3D图形, 仍然是在2维空间绘图, 但可以表达3维信息。例如在机器学习中, contour常用于绘制分类算法的超平面
如果需要绘制真3D图形, 则需要额外导入matplotlib专用3D绘图库:mpl_toolkits, 包括3D版的Axes对象和常用图表的3D版:
- plot3D: 3D版plot, 可用于绘制3维空间的折线图或点图
- scatter3D: 3维散点图
- bar3D: 3维条形图
- contour3D: 3维等高线
1.5 更高级的封装
matplotlib提供了大量丰富的可视化绘图接口, 但仍然存在短板:例如绘图操作略显繁琐、图表不够美观。为此, 在matplotlib基础上产生了一些封装更为便捷的可视化库, 实现更为简单易用的接口和美观的图表形式, 包括:
- pandas.plot: 一个最直接的对matplotlib绘图的封装, 接口方法非常接近
- seaborn: 是对matplotlib的高级封装, 具有更为美观的图形样式和颜色配置, 并提供了常用的统计图形接口, 如pairplot()适用于表达多组数据间的关系
- ggplot: 也是对matplotlib进行二次封装的可视化库, 主要适用于pandas的DataFrame数据结构
2. Seaborn
它是专门为统计可视化而创建的库。
Seaborn 是一个建立在 Matplotlib 基础之上的 Python 数据可视化库, 专注于绘制各种统计图形, 以便更轻松地呈现和理解数据。Seaborn 的设计目标是简化统计数据可视化的过程, 提供高级接口和美观的默认主题, 使得用户能够通过少量的代码实现复杂的图形。Seaborn 提供了一些简单的高级接口, 可以轻松地绘制各种统计图形, 包括散点图、折线图、柱状图、热图等, 而且具有良好的美学效果。Seaborn 在设计时注重美观性, 其默认主题和颜色调色板经过精心选择, 使得绘图更加吸引人。
seaborn 是建立在 matplotlib 之上的。可以使用所学的 matplotlib 知识来修改并使用 seaborn。
import seaborn as sns
sns.pairplot(df, hue="class")
seaborn的几个鲜明特点如下:
- 绘图接口更为集成, 可通过少量参数设置实现大量封装绘图
- 多数图表具有统计学含义, 例如分布、关系、统计、回归等
- 对Pandas和Numpy数据类型支持非常友好
- 风格设置更为多样, 例如风格、绘图环境和颜色配置等
2.1 风格设置
seaborn的风格设置主要分为两类, 其一是风格(style)设置, 其二是环境(context)设置。
2.1.1 风格设置
seaborn设置风格的方法主要有三种:
- set, 通用设置接口
- set_style, 风格专用设置接口, 设置后全局风格随之改变
- axes_style, 设置当前图(axes级)的风格, 同时返回设置后的风格系列参数, 支持with关键字用法
当前支持的风格主要有5种:
- darkgrid, 默认风格
- whitegrid
- dark
- white
- ticks
2.1.2 环境设置
设置环境的方法也有3种:
- set, 通用设置接口
- set_context, 环境设置专用接口, 设置后全局绘图环境随之改变
- plotting_context, 设置当前图(axes级)的绘图环境, 同时返回设置后的环境系列参数, 支持with关键字用法
当前支持的绘图环境主要有4种:
- notebook, 默认环境
- paper
- talk
- poster
2.2 颜色设置
seaborn风格多变的另一大特色就是支持个性化的颜色配置。颜色配置的方法有多种, 常用方法包括以下两个:
- color_palette, 基于RGB原理设置颜色的接口, 可接收一个调色板对象作为参数, 同时可以设置颜色数量
- hls_palette, 基于Hue(色相)、Luminance(亮度)、Saturation(饱和度)原理设置颜色的接口, 除了颜色数量参数外, 另外3个重要参数即是hls
同时, 为了便于查看调色板样式, seaborn还提供了一个专门绘制颜色结果的方法palplot。
2.3 数据集
seaborn自带了一些经典的数据集, 用于基本的绘制图表示例数据。在联网状态下, 可通过load_dataset()接口进行获取, 首次下载后后续即可通过缓存加载。返回数据集格式为Pandas.DataFrame对象。
当前内置了10几个数据集, 常用的经典数据集如下:
- iris:鸢尾花, 与sklearn中数据集一致, 仅有数值型数据
- tips:小费, 主要是中餐和晚餐的数据集, 既有分类数据也有数值数据, 可用于探索数据间的回归关系
- titanic:泰坦尼克, 经典数据集
2.4 常用绘制图表
seaborn内置了大量集成绘图接口, 往往仅需一行代码即可实现美观的图表结果。按照数据类型, 大体可分为连续性(数值变量)和离散型(分类数据)两类接口。
2.4.1 数值变量
2.4.1.1 单变量分布
变量分布可用于表达一组数值的分布趋势, 包括集中程度、离散程度等。seaborn中提供了3种表达单变量分布的绘图接口
-
distplot
distribution+plot, 接口内置了直方图(histogram)、核密度估计图(kde, kernel density estimation)以及rug图(直译为地毯, 绘图方式就是将数值出现的位置原原本本的以小柱状的方式添加在图表底部), 3种图表均可通过相应参数设置开关状态, 默认情况下是绘制hist+kde。
distplot支持3种格式数据:pandas.series、numpy中的1darray以及普通的list类型。 -
kdeplot
kdeplot是一个专门绘制核密度估计图的接口, 虽然distplot中内置了kdeplot图表, 并且可通过仅开启kde开关实现kdeplot的功能, 但kdeplot实际上支持更为丰富的功能, 比如当传入2个变量时绘制的即为热力图效果。 -
rugplot
这是一个不太常用的图表类型, 其绘图方式比较朴素:即原原本本的将变量出现的位置绘制在相应坐标轴上, 同时忽略出现次数的影响。
2.4.1.2 多变量间分布
单变量分布仅可用于观察单一维度的变化关系, 为了探究多变量间分布关系时, 如下绘图接口更为有效:
-
jointplot
joint意为联合, 顾名思义jointplot是一个双变量分布图表接口。绘图结果主要有三部分:绘图主体用于表达两个变量对应的散点图分布, 在其上侧和右侧分别体现2个变量的直方图分布 -
pairplot
当变量数不止2个时, pairplot是查看各变量间分布关系的首选。它将变量的任意两两组合分布绘制成一个子图, 对角线用直方图、而其余子图用相应变量分别作为x、y轴绘制散点图。显然, 绘制结果中的上三角和下三角部分的子图是镜像的。
实际上, 查看seaborn源码可以发现, 其绘图接口大多依赖于一个类实现。例如:jointplot在seaborn中实际上先实现了一个名为JointGrid的类, 然后在调用jointplot时即是调用该类实现。相比之下, JointGrid可以实现更为丰富的可定制绘图接口, 而jointplot则是其一个简单的样例实现。类似地, pairplot则是依赖于PairGrid类实现。
2.4.1.3 关系型图表
seaborn还提供了几个用于表达双变量关系的图表, 主要包括点图和线图两类。主要提供了3个接口, relplot(relation+plot)、scatterplot和lineplot, 其中relplot为figure-level(可简单理解为操作对象是matplotlib中figure), 而后两者是axes-level(对应操作对象是matplotlib中的axes), 但实际上接口调用方式和传参模式都是一致的, 其核心参数主要包括以下4个:
-
data: pandas.dataframe对象, 后面的x、y和hue均为源于data中的某一列值
-
x: 绘图的x轴变量
-
y: 绘图的y轴变量
-
hue: 区分维度, 一般为分类型变量
-
relplot
relplot可通过kind参数选择绘制图表是scatter还是line类型。默认为scatter类型。 -
scatterplot: 也可实现同样的散点图效果
-
lineplot
lineplot不同于matplotlib中的折线图, 会将同一x轴下的多个y轴的统计量(默认为均值)作为折线图中的点的位置, 并辅以阴影表达其置信区间。可用于快速观察点的分布趋势。
2.4.1.4 回归分析
在查看双变量分布关系的基础上, seaborn还提供了简单的回归接口。另外, 还可设置回归模型的阶数, 例如设置order=2时可以拟合出抛物线型回归线。
-
regplot
基础回归模型接口, 即regression+plot。绘图结果为散点图+回归直线即置信区间。另外, 还可通过logistic参数设置是否启用逻辑回归。 -
residplot
residplot提供了拟合后的残差分布图, 相当于先执行lmplot中的回归拟合, 而后将回归值与真实值相减结果作为绘图数据。直观来看, 当残差结果随机分布于y=0上下较小的区间时, 说明具有较好的回归效果。 -
lmplot
lmplot=regplot+FacetGrid, 也是用于绘制回归图表, 但功能相比更为强大, 除了增加hue参数支持分类回归外, 还可添加row和col参数(二者均为FacetGrid中的常规参数, 用于添加多子图的行和列)实现更多的分类回归关系。
2.4.1.5 矩阵图
矩阵图主要用于表达一组数值型数据的大小关系, 在探索数据相关性时也较为实用。
-
heatmap
原原本本的将一组数据以热力图矩阵的形式展现出来, 同时可通过设置数值上下限和颜色板实现更为美观的效果。 -
clustermap
在heatmap的基础上, clustermap进一步挖掘各行数据间的相关性, 并逐一按最小合并的原则进行聚类, 给出了聚类后的热力图
2.4.2 分类数据
2.4.2.1 散点图
分类数据散点图接口主要用于当一列数据是分类变量时。相比于两列数据均为数值型数据, 可以想象分类数据的散点图将会是多条竖直的散点线。绘图接口常用参数是一致的, 主要包括:
- x: 散点图的x轴数据, 一般为分类型数据
- y: 散点图的y轴数据, 一般为数值型数据
- hue: 区分维度, 相当于增加了第三个参数
- data: pandas.dataframe对象, 以上几个参数一般为data中的某一列
常规的散点图接口, 可通过jitter参数开启散点左右"抖动"效果(实际即为在水平方向上加了一个随机数控制x坐标, 默认jitter=True;当设置jitter为False时, 散点图均严格位于一条直线上)
绘图接口有stripplot和swarmplot两种:
- stripplot
- swarmplot
在stripplot的基础上, 不仅将散点图通过抖动来实现相对分离, 而且会严格讲各散点一字排开, 从而便于直观观察散点的分布聚集情况
2.4.2.2 分布图
与数值型变量分布类似, seaborn也提供了几个分类型数据常用的分布绘图接口。且主要参数与前述的散点图接口参数是十分相近的。
-
boxplot
箱线图, 也叫盒须图, 表达了各分类下数据4分位数和离群点信息, 常用于查看数据异常值等 -
boxenplot
是一个增强版的箱线图, 即box+enhenced+plot, 在标准箱线图的基础上增加了更多的分位数信息, 绘图效果更为美观, 信息量更大。 -
lvplot
lvplot=letter value+plot, 是boxenplot的前身, 绘图效果与后者一致。现已被boxenplot所替代, 不再提倡使用。 -
violinplot
小提琴图, 相当于boxplot+kdeplot, 即在标准箱线图的基础上增加了kde图的信息, 从而可更为直观的查看数据分布情况。因其绘图结果常常酷似小提琴形状, 因而得名violinplot。在hue分类仅有2个取值时, 还可通过设置split参数实现左右数据合并显示。
2.4.2.3 统计(估计)图
-
pointplot
pointplot给出了数据的统计量(默认统计量为均值)和相应置信区间(confidence intervals, 默认值为95%, 即参数ci=95), 并以相应的点和线进行绘图显示 -
barplot
与pointplot用折线表达统计量变化不同, barplot以柱状图表达统计量, 而置信区间则与前者一致, 仅仅是适用场景不同而已。 -
countplot
这是一个功能比较简单的统计图表, 仅用于表达各分类值计数, 并以柱状图的形式展现
2.4.2.4 figure-level分类绘图总接口
最后, seaborn还提供了一个用于分类数据绘图的figure-level接口catplot, catplot与其他分类数据绘图接口的关系相当于lmplot与regplot的关系;同时catplot中还可通过kind参数实现前面除countplot外的所有绘图接口, 功能更为强大。kind默认为strip, 此时等效于stripplot接口。
-
catplot
catplot=category+plot, 用其实现分类条件下小提琴图。 -
factorplot
factorplot是catplot的前身, 二者实现功能完全一致, 现已被后者更名替代, 官方不再推荐使用。