超详细Seaborn绘图 ——(二)boxplot & boxenplot
箱形图(Box-plot)又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。
它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比较。箱形图最大的优点就是不受异常值的影响(异常值也称为离群值),可以以一种相对稳定的方式描述数据的离散分布情况。
一、基础概念
一个boxplot主要包含六个数据节点,将一组数据从大到小排列,分别计算出他的上边缘(上限),上四分位数Q3,中位数,下四分位数Q1,下边缘(下限),还有一个异常值。
举例来说:
对于这样一个箱线图
-
中位数=8.5
中位数,即二分之一分位数。所以计算的方法就是将一组数据(此处中位数,特别指是从大到小排列的有序序列)按从小到大的顺序,取中间这个数。
如果原始序列长度n是奇数,那么中位数所在位置是(n+1)/2;如果原始序列长度n是偶数,那么中位数所在位置是n/2,n/2+1,中位数的值等于这两个位置的数的算数平均数 -
上四分位数Q3=9
确定四分位数的位置。虽然具体的计算目前有3*(n+1)/4
与(n-1)/4
两种,但一般使用3*(n+1)/4
-
下四分位数Q1=7
这个下四分位数所在位置计算方法同上。不过是(n+1)/4
-
四分位间距IQR(ΔQ)=2
四分位间距=Q3-Q1 -
上限=10
上限是非异常范围内的最大值。 -
下限=5
下限限是非异常范围内的最小值。 -
中位数(Q2)=8.5
中位数常用于度量数据的中心。一半观测值小于等于该值,而另一半则大于等于该值。 -
平均数=8
平均数就不用多说了 -
异常值
规定大于上四分位数1.5倍四分位数差 的值,或者小于下四分位数1.5倍四分位数差的值,划为异常值
箱线图的作用:
1.直观明了地识别数据批中的异常值
其实箱线图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的耐抗性,多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不会影响箱形图的数据形状,箱线图识别异常值的结果比较客观。由此可见,箱线图在识别异常值方面有一定的优越性。
2.利用箱线图判断数据批的偏态和尾重
对于标准正态分布的样本,只有极少值为异常值。异常值越多说明尾部越重,自由度越小(即自由变动的量的个数);
而偏态表示偏离程度,异常值集中在较小值一侧,则分布呈左偏态;异常值集中在较大值一侧,则分布呈右偏态。
3.利用箱线图比较几批数据的形状
同一数轴上,几批数据的箱线图并行排列,几批数据的中位数、尾长、异常值、分布区间等形状信息便昭然若揭。如上图,可直观得看出第三季度各分公司的销售额大体都在下降。
但箱形图也有他的局限性,比如:不能精确地衡量数据分布的偏态和尾重程度;对于批量比较大的数据,反映的信息更加模糊以及用中位数代表总体评价水平有一定的局限性。
二、boxplot
(一)语法
seaborn.boxplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None,
orient=None, color=None, palette=None, saturation=0.75, width=0.8, dodge=True, fliersize=5,
linewidth=None, whis=1.5, notch=False, ax=None, **kwargs)
输入数据可以通过多种格式传入,包括:
- 格式为列表,numpy 数组或 pandas Series 对象的数据向量可以直接传递给x,y和hue参数。
- 对于长格式的 DataFrame,x,y,和hue参数会决定如何绘制数据。
- 对于宽格式的 DataFrame,每一列数值列都会被绘制。
- 一个数组或向量的列表。
(二)参数详解
-
x
,y
,hue
:数据或向量数据中的变量名称
用于绘制长格式数据的输入。 -
data
:DataFrame,数组,数组列表
用于绘图的数据集。如果x和y都缺失,那么数据将被视为宽格式。否则数据被视为长格式。 -
order
,hue_order
:字符串列表
控制分类变量(对应的条形图)的绘制顺序,若缺失则从数据中推断分类变量的顺序。 -
orient
:“v”或“h”
控制绘图的方向(垂直或水平)。这通常是从输入变量的 dtype 推断出来的,但是当“分类”变量为数值型或绘制宽格式数据时可用于指定绘图的方向。 -
color
:matplotlib
颜色
所有元素的颜色,或渐变调色板的种子颜色。 -
palette
:调色板名称,列表或字典
用于hue
变量的不同级别的颜色。可以从color_palette()
得到一些解释,或者将色调级别映射到matplotlib
颜色的字典。 -
saturation
:float
控制用于绘制颜色的原始饱和度的比例。通常大幅填充在轻微不饱和的颜色下看起来更好,如果您希望绘图颜色与输入颜色规格完美匹配可将其设置为1。 -
width
:float
不使用色调嵌套时完整元素的宽度,或主要分组变量一个级别的所有元素的宽度。 -
dodge
:bool
使用色调嵌套时,元素是否应沿分类轴移动。 -
fliersize
:float
用于表示异常值观察的标记的大小。 -
linewidth
:float
构图元素的灰线宽度。 -
whis
:float
控制在超过高低四分位数时 IQR (四分位间距)的比例,因此需要延长绘制的触须线段。超出此范围的点将被识别为异常值。 -
notch
:boolean
是否使矩形框“凹陷”以指示中位数的置信区间。还可以通过plt.boxplot
的一些参数来控制 -
ax
:matplotlib轴
绘图时使用的 Axes 轴对象,否则使用当前 Axes 轴对象 -
kwargs
:键值映射
其他在绘图时传给plt.boxplot的参数
(三)实例
先简单地画一个boxplot
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
%matplotlib inline
# 显示正负号与中文不显示问题
plt.rcParams['axes.unicode_minus'] = False
sns.set_style('darkgrid', {'font.sans-serif':['SimHei', 'Arial']})
# 去除部分warning
import warnings
warnings.filterwarnings('ignore')
plt.figure(dpi=150)
L = [3,2,1,0,4]
sns.boxplot(L)
s = pd.Series(L)
print('平均数:',s.median())
print('')
print('下四分位数:',s.quantile(0.25))
print('')
print('中位数:',s.quantile(0.5))
print('')
print('上四分位数:',s.quantile(0.75))
导入tips数据集进行后续的操作
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',data=tips)
根据 2 个分类变量嵌套分组绘制一个箱型图
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',hue='sex',data=tips)
通过显式传入参数指定顺序控制箱型图的显示顺序
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',hue='sex',data=tips,
order=['Sun','Sat','Fri','Thur'])
通过palette修改每个类别的颜色
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',hue='sex',data=tips,
palette='Set2',saturation=0.4)
变成横向的
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(y='day',x='tip',hue='sex',data=tips,
palette='Set2',saturation=0.4)
修改异常点的大小
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',hue='sex',data=tips,fliersize=1)
人工改变异常值范围
默认异常值为大于Q3+1.5IQR或小于Q1-1.5IQR的值。通过whis
参数可以改变IQR的因数大小进而改变异常值范围
例如:
对于以下数据集,Q1=1.25,Q3=3.25,IQR=2
因此异常值的返回为(6.25,+∞)、(-∞,-1.75)
所以L中的8为异常值
plt.figure(dpi=150)
L = [3,2,1,0,4,8]
sns.boxplot(L)
s = pd.Series(L)
print('平均数:',s.median())
print('')
print('下四分位数:',s.quantile(0.25))
print('')
print('中位数:',s.quantile(0.5))
print('')
print('上四分位数:',s.quantile(0.75))
但是如果通过whis
人工修改异常值范围,例如设定whis=3
那么异常值的界限就成了Q3+3*IQR
和Q1-3*IQR
即(9.75,+∞)、(-∞,-4.75)
那么8就不是异常值了
plt.figure(dpi=150)
L = [3,2,1,0,4,8]
sns.boxplot(L,whis=3)
突出中位数的置信区间
plt.figure(dpi=150)
tips = sns.load_dataset('tips')
sns.boxplot(x='day',y='tip',hue='sex',data=tips,notch=True)
三、boxenplot
boxenplot是为更大的数据集绘制增强的箱型图。这种风格的绘图最初被命名为“信值图”,因为它显示了大量被定义为“置信区间”的分位数。它类似于绘制分布的非参数表示的箱形图,其中所有特征对应于实际观察的数值点。通过绘制更多分位数,它提供了有关分布形状的更多信息,特别是尾部数据的分布。
(一)语法
seaborn.boxenplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, orient=None,
color=None, palette=None, saturation=0.75, width=0.8, dodge=True,
k_depth='proportion',linewidth=None, scale='exponential', outlier_prop=None,
ax=None, **kwargs)
(二)参数详解
作为增强版的boxplot,boxenplot很多参数和boxplot是相似的。现在就剩下不同的参数进行详解
-
k_depth
:“proportion” 或 “tukey” 或 “trustworthy”
通过增大百分比的粒度控制绘制的盒形图数目。每个参数代表利用不同的统计特性对异常值的数量做出不同的假设。 -
scale
:“linear” 或 “exponential” 或 “area”
用于控制增强箱型图宽度的方法。所有参数都会给显示效果造成影响。 “linear” 通过恒定的线性因子减小宽度,“exponential” 使用未覆盖的数据的比例调整宽度, “area” 与所覆盖的数据的百分比成比例。 -
outlier_prop
:float
被认为是异常值的数据比例。与 k_depth 结合使用以确定要绘制的百分位数。默认值为 0.007 作为异常值的比例。该参数取值应在[0,1]范围内。
(三)实例
绘制一个独立的横向增强箱型图
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x=tips["total_bill"])
根据分类变量分组绘制一个纵向的增强箱型图
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',data=tips)
根据 2 个分类变量嵌套分组绘制一个增强箱型图
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips)
改变盒形图数目
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips,
k_depth='tukey')
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips,
k_depth='trustworthy')
控制增强箱型图宽度
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips,
scale='linear')
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips,
scale='exponential')
plt.figure(dpi=150)
tips = sns.load_dataset("tips")
sns.boxenplot(x='day',y='total_bill',hue='smoker',data=tips,
scale='area')
更多推荐
所有评论(0)