数据可视化|用箱线图进行对比分析

林骥
林骥
林骥
44
文章
0
评论
2021-08-0314:44:39 评论 5,094 4429字
摘要

你好,我是林骥。箱线图,形状有点像箱子连着两条须线,主要用于反映数据的分布特征,可以看出数据的对称性和分散度等信息,适合用于对比分析多组数据的分布情况。

一、

你好,我是林骥。

箱线图,形状有点像箱子连着两条须线,主要用于反映数据的分布特征,可以看出数据的对称性和分散度等信息,适合用于对比分析多组数据的分布情况。

比如说,调查用户对某产品不同功能的满意度,得到的数据如下表:

数据可视化|用箱线图进行对比分析

我们可以用箱线图来进行对比分析,效果图如下:

数据可视化|用箱线图进行对比分析

在上面的图中,箱体的颜色,代表用户满意度的高低,橙色代表满意度较低,灰色代表满意度一般,蓝色代表满意度较高。

箱体中的橙色线条,代表中位数,它一般不会受到极大或极小值的影响,所以提高了对数据分布的代表性。

箱体中的灰色虚线,代表平均值,是一个常用的统计量,它的缺点是容易受极端数据的影响。

比如说,把 10 个普通人和 1 个世界首富,放在一起计算平均收入,如果用这个平均收入,去说明大家的收入很高,那么结果就很难让人信服。

箱体两头的须线,代表数据的离散程度,须线越长,代表数据越分散,须线越短,代表数据越集中。

二、

接下来,我们看看用 matplotlib 画图的具体步骤。

首先,导入所需的库,并设置中文字体和定义颜色等。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# 导入所需的库import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as plt# 正常显示中文标签mpl.rcParams["font.sans-serif"] = ["SimHei"]# 自动适应布局mpl.rcParams.update({"figure.autolayout": True})# 正常显示负号mpl.rcParams["axes.unicode_minus"] = False# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色c = {"蓝色":"#00589F", "深蓝色":"#003867", "浅蓝色":"#5D9BCF",     "灰色":"#999999", "深灰色":"#666666", "浅灰色":"#CCCCCC",     "橙色":"#F68F00", "深橙色":"#A05D00", "浅橙色":"#FBC171"}

其次,从 Excel 文件中读取随机模拟的数据,并定义画图用的数据。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# 数据源路径filepath="./data/问卷调查结果3.xlsx"# 读取 Excel文件df = pd.read_excel(filepath, index_col="调查用户")# 定义画图用的数据labels = df.columnsdata = df.values

接下来,开始用「面向对象」的方法进行画图。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# 使用「面向对象」的方法画图,定义图片的大小fig, ax = plt.subplots(figsize=(8, 6))# 设置背景颜色fig.set_facecolor("w")ax.set_facecolor("w")# 设置箱体的属性boxprops = {"color":c["灰色"]}# 设置中位线参数medianprops = {"color":c["橙色"]}# 设置均值的属性meanprops = {"color":c["灰色"]}# 设置箱线图顶端和末端线条的属性capprops = {"color":c["灰色"]}# 设置须线的属性whiskerprops = {"color":c["灰色"]}# 绘制箱线图,whis 用来控制箱须包含数据的范围,这里设置得比较大,是为了不让图中出现异常点bplot = ax.boxplot(data, vert=False, patch_artist=True, labels=labels, showmeans=True, whis=5, meanline=True,                    boxprops=boxprops, medianprops=medianprops, meanprops=meanprops, capprops=capprops, whiskerprops=whiskerprops)# 设置标题ax.set_title("
用户满意度的分布情况
", loc="left", size=26, color=c["深灰色"])# 倒转 Y 轴,让第一个功能排在最上面ax.invert_yaxis()# 隐藏 Y 轴的刻度线ax.tick_params(axis="y", which="major", length=0)# 设置 X 轴范围ax.set_xlim(0.76, 1.02)# 隐藏 X 轴ax.xaxis.set_visible(False)# 标记箱线代表的含义ax.text(min(data[:,0]), 1, "%.1f%% "%(min(data[:,0])*100)+"
最小值 ", ha="right", fontsize=12, color=c["深灰色"], va="center")ax.text(np.mean(data[:,0]), 0.7, " %.1f%%"%(np.mean(data[:,0])*100)+"
 平均值", ha="center", fontsize=12, color=c["深灰色"], va="bottom")ax.text(np.median(data[:,0]), 1.3, " %.1f%%"%(np.median(data[:,0])*100)+"
中位数", ha="center", fontsize=12, color=c["橙色"], va="top")ax.text(max(data[:,0]), 1, " %.1f%%"%(max(data[:,0])*100)+"
 最大值", ha="left", fontsize=12, color=c["深灰色"], va="center")# 循环添加数据标签for i in range(1, len(labels)):    ax.text(min(data[:,i]), i+1, "%.1f%% "%(min(data[:,i])*100), ha="right", fontsize=12, color=c["深灰色"], va="center")    ax.text(np.mean(data[:,i]), i+0.7, " %.1f%%"%(np.mean(data[:,i])*100), ha="center", fontsize=12, color=c["深灰色"], va="bottom")    ax.text(np.median(data[:,i]), i+1.3, " %.1f%%"%(np.median(data[:,i])*100), ha="center", fontsize=12, color=c["橙色"], va="top")    ax.text(max(data[:,i]), i+1, " %.1f%%"%(max(data[:,i])*100), ha="left", fontsize=12, color=c["深灰色"], va="center")# 填充箱体的颜色colors = [c["浅橙色"], c["浅橙色"], c["浅灰色"], c["蓝色"], c["蓝色"]]for patch, color in zip(bplot["boxes"], colors):    patch.set_facecolor(color)# 隐藏边框ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["bottom"].set_visible(False)ax.spines["left"].set_visible(False)# 设置坐标标签字体大小和颜色ax.tick_params(labelsize=16, colors=c["深灰色"])# 用百分比格式显示坐标轴def to_percent(temp, position=1):    return "%.0f"%(100 * temp) + "%"formatter = mpl.ticker.FuncFormatter(to_percent)ax.xaxis.set_major_formatter(formatter)plt.savefig("用户满意度的分布情况.jpeg")plt.show()

你可以前往 https://github.com/linjiwx/mp 下载画图用的数据和完整代码。

下面是用 matplotlib 画箱线图 boxplot 的主要参数说明,以备查询参考:

x:指定要绘制箱线图的数据;

notch:是否是凹口的形式展现箱线图,默认非凹口;

sym:指定异常点的形状,默认为 + 号显示;

vert:是否需要将箱线图垂直摆放,默认垂直摆放;

whis:指定上下须与上下四分位的距离,默认为 1.5 倍的四分位差;

positions:指定箱线图的位置,默认为 [0, 1, 2 …];

widths:指定箱线图的宽度,默认为 0.5;

patch_artist:是否填充箱体的颜色;

meanline:是否用线的形式表示均值,默认用点来表示;

showmeans:是否显示均值,默认不显示;

showcaps:是否显示箱线图顶端和末端的两条线,默认显示;

showbox:是否显示箱线图的箱体,默认显示;

showfliers:是否显示异常值,默认显示;

boxprops:设置箱体的属性,如边框色,填充色等;

labels:为箱线图添加标签,类似于图例的作用;

filerprops:设置异常值的属性,如异常点的形状、大小、填充色等;

medianprops:设置中位数的属性,如线的类型、粗细等;

meanprops:设置均值的属性,如点的大小、颜色等;

capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等;

whiskerprops:设置须线的属性,如颜色、粗细、线的类型等。

三、

在一个箱线图中,通常包含以下 5 个统计量:

1、第一个四分位数(Q1);

2、中位数(Median);

3、第三个四分位数(Q3);

4、「最小值」(Q1 - 1.5 * IQR);

5、「最大值」(Q3 + 1.5 * IQR)。

其中 IQR 代表四分位间距,等于 Q3 - Q1,即从 Q1 到 Q3 的距离,1.5 是 matplotlib 中 boxplot 函数 whis 参数的默认值。

需要注意的是,箱线图中的「最小值」未必是真的最小值,因为箱线图可能会把离群值排除在外。

比如下面这张图,绿色圆圈代表离群值。

数据可视化|用箱线图进行对比分析

上面把箱线图与正态分布图进行对比,应该能帮你更好地理解箱线图中各统计量代表的含义。

 

 

 

End.

爱数据网专栏作者:林骥

作者介绍:数据赋能者,专注数据分析 10 多年。

个人公众号:林骥(linjiwx)

本文为挖数网专栏作者原创文章,未经允许禁止转载,需要转载请微信联系授权(微信号:lovedata0520)

更多文章前往爱数据社区网站首页浏览http://www.itongji.cn/

  • 我的微信公众号
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: