可视化神器Plotly玩转箱形图
在之前的文章中介绍过如何使用Plotly绘制柱状图、饼图、散点图等,都是比较常用的可视化图表呈现方式。本文介绍的是利用Plotly绘制统计图形中的一种:箱型图。
扩展阅读
Plotly的文章会形成连载系列,前面8篇Plotly可视化文章分别是:
- 酷炫!36张图爱上高级可视化神器Plotly_Express
- Plotly玩转散点图
- Plotly玩转饼图
- Plotly玩转漏斗图
- Plotly玩转柱状图
- Plotly玩转气泡图
- Plotly玩转股票图
- Plotly玩转甘特图
箱型图
什么是箱型图
箱型图是一种用作显示一组数据分散情况资料的统计图,它能够快速显示数据中的异常值情况,其形状像盒子,因而得名,也称之为盒须图、盒式图、盒装图或者箱型图。
1977年,美国著名数学家John W. Tukey首先在他的著作《Exploratory Data Analysis》中介绍了箱形图。
四分位数
四分位数是箱型图中最为重要的概念,下面介绍四分位数的相关知识。
四分位数(Quartile)是统计学中分位数的一种,即把所有数值由小到大分成四等份,处于三个分割点位置的数值就是四分位数。
- 第一四分位数(Q1):也称下四分位数(Lower Quartile),等于该样本中所有数值由小到大排列后第25%的数字。
- 第二四分位数(Q2):也称中位数(Middle Quartile or Median),等于该样本中所有数值由小到大排列后第50%的数字。
- 第三四分位数(Q3):也称上四分位数(Upper Quartile),等于该样本中所有数值由小到大排列后第75%的数字。
Q3和Q1的差距称为四分位距(InterQuartile Range, IQR):IQR=Q3-Q1
四分位数计算
在计算四分位数的时候我们需要先计算四分位数的位置,3个四分位数的位置计算:
1 | # n表示样本个数 |
通过一个例子来进行讲解位置的计算,有11个数值无序排列如下:
1 | 6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36 |
我们先将数值按照从小到大排列:
1 | 6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49 |
那么3个四分位数的位置分别为:
1 | # n=11表示样本个数 |
对应的3个四分位数为:Q1=15,Q2=40,Q3=43,IQR=Q3-Q1=28
如果计算出来位置刚好不是整数,即n+1不是4的整数倍,则一般取该位置两边数的加权平均值(也有直接取平均值的),位置离得越近的数值权重越高,一般权重为:1−小数位。比如对于以下样本:
1 | 2,3,4,5 |
那么计算Q1的位置为:(4+1)/ 4= 1.25,且更靠近2,那么Q1为:
1 | Q1=2 * (1 - 0.25) + 3 * 0.25 = 2.25 # 0.25是小数位 |
如果直接取平均值:Q1= (2+3) / 2 = 2.5
4种不同箱型图比较
来自维基百科上4种不同箱型图的比较:
箱型图作用
- 它可以粗略地看出数据是否具有有对称性
- 显示数据分布的分散程度等信息,特别可以用于对几个样本的比较。
- 反映一组或多组连续型定量数据分布的中心位置和散布范围
- 分析不同类别数据各层次水平差异,还能揭示数据间离散程度、异常值、分布差异等
箱形图最大的优点就是不受异常值的影响,能够准确稳定地描绘出数据的离散分布情况,同时也利于数据的清洗。
数据集
下面介绍各种需求场景下箱型图的绘制,本文中使用的数据大部分是plotly中自带的消费tips数据集:
1 | import pandas as pd |
本文绘图使用的也是两种方法:
1 | import plotly_express as px # 1、px实现 |
基于px绘制箱型图
基于点的箱体图
使用每个数据的点作为标记marker来绘制箱体图,使用的方法是:px.strip()
1 | # 使用的方法是:px.strip() |
1 | # 使用的方法是:px.strip() |
基础箱型图
1 | fig = px.box( |
分组箱体图
针对有不同分类的组绘制箱体图:
1 | fig = px.box( |
再来一个稍微多字段的分组箱体图:
1 | fig = px.box( |
带散点的箱体图
有时候我们在绘制箱体图的时候,需要带上散点,散点表示的就是原始数据情况。点的取值有4种情况:
- all:全部
- outliers:离群点
- suspectedoutliers:可疑离群点
- False:不显示
1 | fig = px.box( |
带四分位数的箱体图
计算散点插值方法有3种:
- linear:线性差值方法,默认
- exclusive:排除算法统计。如果样本是奇数,则不包含任何一半的中位数,Q1是下半部分的中位数,Q3是上半部分的中位数
- inclusive:包含算法统计;如果样本是奇数,则在两个半部分都包含中位数,Q1是下半部分的中位数,Q3是上半部分的中位数
1 | fig = px.box( |
3种不同四分位数显示方法比较
模拟一份数据集:
1 | data = [10,20,30,40,50,60,70,80,90] |
使用melt方法对上面的数据进行合并和转化,使用到了一个melt函数:
- d_vars:不需要被转换的列名
- value_vars:需要转换的列名,如果剩下的列全部都要转换,就不用写
- var_name和value_name是自定义设置对应的列名。
- col_level:如果列是MultiIndex,则使用此级别
1 | ## 3种不同算法之间的比较结果 |
添加数据轨迹和抖动间距jitter:
1 | fig = px.box( |
带缺口的箱体图
1 | fig = px.box( |
基于go绘制箱型图
基础箱体图绘制
1 | import plotly.graph_objects as go |
分组箱体图绘制
1 | np.random.seed(1) # 设置随机种子 |
1 | fig = go.Figure() |
我们还可以设置图形的颜色:
1 | fig = go.Figure() |
1 | import plotly.graph_objects as go |
全样式箱体图
1 | import plotly.graph_objects as go |
3种不同方式下四分位数的显示
对3种不同计算方法下四分位数的显示:
1 | import plotly.graph_objects as go |
通过上图可以清楚地看到3种不同差值方法的区别。
水平箱型图
1 | x1 = np.random.randn(50) |
分组水平箱型图
1 | import plotly.graph_objects as go |
带有均值和方差的箱体图
1 | import plotly.graph_objects as go |
4种不同数据点的显示方式
1 | import plotly.graph_objects as go |
彩虹箱型图
1 | import plotly.graph_objects as go |
具体的绘图代码为:
1 | fig = go.Figure(data=[go.Box( |