Seaborn 用直方图绘制分布图,其中 stat = 密度或概率?

2024-04-24

我知道,默认情况下,直方图方法是计算出现次数。相反,我们可以用密度或概率来可视化分布。

sns.displot(data, stat = 'density')

or

sns.displot(data, stat = 'probability')

我的问题是我应该使用哪些情况统计='密度' or 统计='概率' ?


stat = 'density'创建概率密度函数 (PDF) (维基百科 https://en.wikipedia.org/wiki/Probability_density_function).
正如 JohanC 在评论中提到的,PDF 的一个关键方面是曲线下的面积(或所有条形在一起)为 1。因此,条形宽度和条形高度都被考虑在内。

stat = 'probability'创建相同的条形(包括相同的宽度),但每个高度(y 轴值)直接说明该箱的概率。所有条形高度之和为 1。


使用哪一种取决于你想用情节“展示”什么以及观众是什么。

'probability'对于堆叠条形而言更直观且易于理解。
'density'更适合熟悉 PDF 的专家受众。

另外,由于 PDF 通常显示连续曲线'density' with displot并且 bins 更适合大量的 bins,而'probability' with displot也可以直观地工作,例如2 个垃圾箱。


Seaborn教程可视化数据分布 - 标准化直方图统计 https://seaborn.pydata.org/tutorial/distributions.html#normalized-histogram-statistics提供解释和示例图。
为了可视化该答案中的陈述,下面使用了减少的示例数据和图表以及不同的解释角度。


数据准备:(df 转换保持基本 - 具有# print以便于交叉检查)

import pandas as pd
import seaborn as sns


penguins = sns.load_dataset("penguins")
penguins_strip = penguins[['flipper_length_mm', 'sex']].dropna()
# print(penguins_strip)
print('Female and Male')
print(f'range: {penguins_strip["flipper_length_mm"].max() - penguins_strip["flipper_length_mm"].min()}')
print(f'len: {len(penguins_strip)}')

penguins_strip_male = penguins_strip[penguins_strip['sex'] == 'Male']
# print(penguins_strip_male)
print('Male only')
print(f'range: {penguins_strip_male["flipper_length_mm"].max() - penguins_strip_male["flipper_length_mm"].min()}')
print(f'len: {len(penguins_strip_male)}')
Female and Male
range: 59.0
len: 333

Male only
range: 53.0
len: 168

在顶部显示值的函数displot酒吧 - 很大程度上基于此特伦顿·麦金尼的回答 https://stackoverflow.com/a/68850867

def show_values(plot):
    for ax in plot.axes.ravel():
        # add annotations
        for c in ax.containers:
            # custom label calculates percent and add an empty string so 0 value bars don't have a number
            labels = [f'{w:0.5f}' if (w := v.get_height()) > 0 else '' for v in c]
            ax.bar_label(c, labels=labels, label_type='edge', fontsize=8, rotation=0, padding=2)
        ax.margins(y=0.2)

注意:由于显示的浮点数字有限,某些以下计算均四舍五入.


2 个垃圾箱,仅限“男性”脚蹼

默认显示图(无stat):

'probability'绘图 - 请注意每个 bin 总计为 1 的直观 y 轴概率。

'density'绘图 - 请参阅下面的面积计算

0.02156 * (53/2) = 0.57134
0.01617 * (53/2) = 0.428505
# see data preparation above, range is 53, and it's 2 bins

这两个面积相加为 1(四舍五入)。
你可以试试bins_nr = 1并轻松检查该区域。而对于'probability' with bins_nr = 1y 将仅为 1。

地块代码

bins_nr = 2

displot_default = sns.displot(penguins_strip_male, x="flipper_length_mm", hue="sex", 
                              bins=bins_nr, multiple="dodge")
show_values(displot_default)
    
displot_density = sns.displot(penguins_strip_male, x="flipper_length_mm", hue="sex", 
                              bins=bins_nr, multiple="dodge", stat = 'density')
show_values(displot_density)
        
displot_probability = sns.displot(penguins_strip_male, x="flipper_length_mm", hue="sex", 
                                  bins=bins_nr, multiple="dodge", stat = 'probability')
show_values(displot_probability)

堆积图示例(仅适用于'probability')

displot_probability_stacked = sns.displot(penguins_strip, x="flipper_length_mm", hue="sex", 
                                  bins=bins_nr, multiple="stack", stat = 'probability')
show_values(displot_probability_stacked)

插件:如果你想知道common_norm教程检查中的示例

displot_density = sns.displot(penguins_strip, x="flipper_length_mm", hue="sex", 
                              bins=bins_nr, multiple="dodge", stat = 'density')
show_values(displot_density)

displot_density_common = sns.displot(penguins_strip, x="flipper_length_mm", hue="sex", bins=bins_nr, 
                multiple="dodge", stat = 'density', common_norm=False)
show_values(displot_density_common)

并计算面积。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Seaborn 用直方图绘制分布图,其中 stat = 密度或概率? 的相关文章

随机推荐