小言_互联网的博客

箱形图、小提琴图、直方图……统统可以卡通化!

606人阅读  评论(0)

全文共11345字,预计学习时长23分钟或更长

对于数据科学家来说,可视化工具比比皆是,因此,退一步去钻研每种可视化的类型及其适用的最佳案例就变得十分重要。为了发挥工具的最佳效用,有时可以考虑将其拟人化,甚至是将其变成卡通人物。

为了更好地理解图表,本文将其设计成了一系列卡通人物。

背景——数据集

这份有关谷物的数据集(https://www.kaggle.com/crawford/80-cereals)来自Kaggle,可用以制作各类图表。下载并保存该数据集,就可以运行以下绘图代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv(‘./dataset/cereal.csv’)
df[‘cal_per_cup’] = df.calories/df.cups # adding column to look at
 calorie content per cup rather than per serving

具体而言,绘图所需数据集中的每个样本都必须具有定量值或连续值(例如热量、纤维等非分类变量),制图的重点在于如何展示这些定量值。但同时一些分类变量(例如谷物位于顶部、中部还是底部货架)也必不可少,以便按照类别划分样本,并展示出每种样本的定量值。这一谷物数据集较好地融合了两者。

分布族

这是一个幸福的大家庭——箱形图、直方图、小提琴图、箱形图。虽然它们长相各异,但如果深入了解,你就会发现每种图形都以相似的方式揭示数据集的构成。

爸爸妈妈:箱形图Borat和Wanda

这个图表家庭会告诉你,用大量不同的数据样本测量同一个值的意义何在。无论数据集是正常或是已被扭曲,这些图表都能找出样本的中位数(三个孩子甚至可以判断样本是否为多模态分布)。

来认识一下箱形图Borat和Wanda(不过Wanda更喜欢别人叫她盒须图)。他们在一次蹦床聚会上相遇,Wanda在蹦床上弹跳时,突然丢失了一个异常值,这个异常值砸到了Borat头上。Borat把异常值还给了Wanda,然后他们就在一起了。

箱形图喜欢蹦床,所以它们总是出现在x轴的高处和低处。

Borat和Wanda志趣相投。Borat喜欢保持清爽的外表,表达总是简洁凝练。而Wanda则更喜欢打扮一些,在解释一件事时,她会多花点时间介绍细节,因为她希望别人充分理解她所发现的异常现象。

箱形图的实际应用

“Borat”代表的是形式最简单的箱形图(或称盒须图),它能提供五条关于分布的信息:最大值、最小值、中位数、下四分位数及上四分位数。

注意,在下面的代码中,图表的默认参数并不会将上下边缘线设置成最大值和最小值,所以必须在代码里加上“whis='range'”这一条件。

plt.figure(figsize=(4, 8))
sns.boxplot(df.cal_per_cup, whis=’range’,
 orient=’v’, color=’#BFD0FE’)
plt.ylabel(‘Calories Per Cup’)
plt.title(‘Distribution of Calories in Cereals’);

“Wanda”代表的是一种更为常见的箱形图(有时被称为图基箱形图),能够通过调整参数,选择性地传达信息。它默认将上边缘设置在1.5四分位数范围内(IQR)的最大点,IQR即下四分位数和上四分位数之间的差值。也就是说,上边缘在上四位数1.5倍IQR处,下边缘位于下四分位数1.5倍IQR处。上边缘线以上、下边缘线以下的值都被划为异常值。

plt.figure(figsize=(4, 8))
sns.boxplot(df.cal_per_cup,
 orient=’v’, color=’#F6A6A0')
plt.ylabel(‘Calories Per Cup’)
plt.title(‘Distribution of Calories in Cereals’);

箱形图可用于展示数据集的扩散和偏离程度。如果想要对多种分布情况进行比较,箱形图也会派上用场。举个例子,以下是根据货架位置对谷物进行分类后,每杯谷物中热量的分布情况。

plt.figure(figsize=(15, 8))
sns.boxplot([‘Bottom Shelf’, ‘Middle Shelf’, ‘Top Shelf’],
  [df[df.shelf==1].cal_per_cup,
df[df.shelf==2].cal_per_cup, df[df.shelf==3].cal_per_cup],
orient=’v’, color=’#F6A6A0')
plt.ylabel(‘Calories Per Cup’)
plt.title(‘Distribution of Calories in Cereals by Shelf Placement’,
 fontsize=20);

根据货架位置对数据进行分类,很快可以发现原始箱形图中所有的异常值都来自顶层货架上的谷物。这表明顶层货架上谷物的热量中位数是最高的,而且其中不仅有热量最高的谷物,也有热量最低的谷物。

儿子:直方图Howard

Borat和Wanda在一起后生了三个孩子,一个男孩(直方图Howard)和一对双胞胎女儿(小提琴图Viola和Violet)。

这是直方图Howard。他总喜欢躺着,给你一个直观的展示,让你自己做结论。他一般不喜欢掩饰条柱之间形成的阶梯,也不愿费力去展示处理数据的手段、数据的中位数或百分数。不过心情愉悦时,他也能好好打扮一番,清楚地展示出这些细节——甚至更多细节。

Howard的边缘参差不齐,这取决于他展示的内容以及图中所用的条柱数量。他出了名的懒,一般只有他老是躺着。不过偶尔时间合适时,他也会站起来,比如为了拍家庭合照。

直方图的实际应用

直方图包含更多关于分布形状的信息——是高斯分布、均匀分布还是多模态分布?通常来说,直方图不会直观地显示中位数或四分位数的位置,但如果需要的话,可以人为设置添加。

在创建直方图时,应该认真考虑所用条柱的数量,因为这会影响直方图的清晰度,而且每一数据集所需要的条柱数量都不尽相同(为了更好地理解数据,我经常会同时在几张图表中设置不同数量的条柱)。在以下代码中,将条柱数量分别设置为5、20、50,分别用于展示很少条柱,较多条柱和非常多条柱的情况。

plt.figure(figsize=(8, 4))
plt.hist(df.cal_per_cup, bins=20,
color=’#BDFCC8', edgecolor=”#1F8F50")
plt.ylabel(‘Calories Per Cup’)
plt.title(‘Distribution of Calories in Cereals’);

以上直方图显示了热量分布。中间的图表有20个条柱,可以清楚看到,其热量分布接近于高斯分布,右侧有一条比较长的尾巴,接近正偏态分布。左图中由于条状数量太少,无法判断热量为50-200的谷物的分布情况(可能是高斯分布,可能是均匀分布,也可能是其他)。右图则条柱过多,包含的信息过多,以致难以描述。

直方图也可以用于比较多个数据集,但这并不是我的最爱。可以将直方图重叠(最多重叠三个数据集),也可以将几个直方图并列进行比较。

此外,还可以在散点图周围创建边缘直方图,以展示一对定量变量之间的关系。下图是有关谷物数据集中纤维与热量关系的直方图:

sns.jointplot(x=df.cal_per_cup, y=df.fiber, kind=’scatter’,
 color=’#1F8F50');

此图用于比较谷物中热量的分布情况与纤维的分布情况。中部是用于比较两个变量的散点图,顶部是热量分布的直方图,右侧是纤维分布的直方图。

双胞胎女儿:小提琴图Violia和Violet

Viola和Violet总是背对背—而且经常(但并不总是!)互相对称。在直方图Howard里经常能看到坎坷的阶梯,但Viola和Violet却喜欢穿紧身裤,所以她们俩的表面总是那么光滑。

小提琴图的实际应用

小提琴图具备箱形图的一些特征,但它们同时也是基于核密度估计(KDE)建构的——KDE能够高效抹去你在直方图中所能看见的阶梯(所以我说Viola和Violet总是穿着紧身裤,表面光滑)。

plt.figure(figsize=(4, 8))
sns.violinplot(df.cal_per_cup, color=’#F0BFFF’, orient=’v’)
plt.ylabel(‘Calories Per Cup’)
plt.title(‘Distribution of Calories in Cereals’);

和箱形图一样,小提琴图也适用于将两个数据集并列进行比较。可参照以下根据货架位置进行分类的数据:

plt.figure(figsize=(15, 8))
sns.violinplot(x=df.shelf, y=df.cal_per_cup,
 color=’#F0BFFF’)plt.xticks([0,1,2], [‘Bottom Shelf’, ‘Middle Shelf’,
 ‘Top Shelf’])
plt.ylabel(‘Calories Per Cup’, fontsize=16)
plt.xlabel(‘Cereal Placement’, fontsize=16)
plt.title(‘Distribution of Calories in Cereals by Shelf Placement’,
 fontsize=20)
plt.tight_layout()

小提琴图的另一个重要特点就是,如果你希望用两种分类标准来展示数据,可以对其进行拆分,在左边放一组数据集的KDE(平滑后的直方图),右边放另一组数据集的KDE(这就是为什么Viola和Violet不是同卵双胞胎——她们有时看起来截然不同),中间是合并数据集的中间值及其他值。

下图将General Mills生产的谷物和Kelloggs生产的谷物(这是数据集中最大的两家谷物生产商)进行了分类,并分别展示了每杯谷物中的热量。

plt.figure(figsize=(15, 8))
plot = sns.violinplot(x=df[(df.mfr == ‘K’) |(df.mfr == ‘G’)].shelf,
  y=df[(df.mfr == ‘K’) |(df.mfr == ‘G’)].cal_per_cup,
 hue=df[(df.mfr == ‘K’) |(df.mfr == ‘G’)].mfr,
 split=True, color=’#F0BFFF’)
handles, labels = plot.get_legend_handles_labels()
plt.xticks([0,1,2], [‘Bottom Shelf’, ‘Middle Shelf’, ‘Top Shelf’])
plt.ylabel(‘Calories Per Cup’, fontsize=16)
plt.xlabel(‘Cereal Placement’, fontsize=16)
plt.legend([handles[0], handles[1]], [‘Kelloggs’, ‘General Mills’],
 title=’Manufacturer’)
plt.title(‘Distribution of Calories in Cereals \nby Shelf Placement and
 Manufacturer’, fontsize=20)
plt.tight_layout();

传送门:https://github.com/msiboni88/DisplayingDistributions/blob/master/Displaying Distributions.ipynb

留言 点赞 关注

我们一起分享AI学习与发展的干货
欢迎关注全平台AI垂类自媒体 “读芯术”

 

(添加小编微信:dxsxbb,加入读者圈,一起讨论最新鲜的人工智能科技哦~)


转载:https://blog.csdn.net/duxinshuxiaobian/article/details/101526205
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场