如何使用海运dislot/histlot/dislot绘制百分比

2022-02-27 00:00:00 python pandas seaborn

问题描述

有没有办法在dislot上绘制百分比而不是计数?

ax = sns.FacetGrid(telcom, hue='Churn', palette=["teal", "crimson"], size=5, aspect=1)
ax = ax.map(sns.distplot, "tenure",  hist=True, kde=False)
ax.fig.suptitle('Tenure distribution in customer churn', y=1, fontsize=16, fontweight='bold');
plt.legend();


解决方案

  • 截至seaborn 0.11.2
    • seaborn.distplot替换为图形级别seaborn.displot和轴级seaborn.histplot,它们有一个stat参数。使用stat='percent'
  • 对于这两种类型的绘图,请使用common_binscommon_norm进行试验。
    • 例如,common_norm=True将显示百分比作为整个人口的一部分,而False将显示相对于组的百分比。
  • 此answer中显示的实现说明如何添加批注。
import seaborn as sns
import matplotlib.pyplot as ply

# data
data = sns.load_dataset('titanic')

图形级别

p = sns.displot(data=data, x='age', stat='percent', hue='sex', height=3)
plt.show()

p = sns.displot(data=data, x='age', stat='percent', col='sex', height=3)
plt.show()

  • labels中使用的类型批注(:=)需要python >= 3.8。可以使用for-loop实现,而不使用:=
fg = sns.displot(data=data, x='age', stat='percent', col='sex', height=3.5, aspect=1.25)

for ax in fg.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.1f}%' if (w := v.get_height()) > 0 else '' for v in c]

        ax.bar_label(c, labels=labels, label_type='edge', fontsize=8, rotation=90, padding=2)
    
    ax.margins(y=0.2)

plt.show()

轴级别

fig = plt.figure(figsize=(4, 3))
p = sns.histplot(data=data, x='age', stat='percent', hue='sex')
plt.show()

按组列出的百分比

  • 使用common_norm=参数
  • 参见seaborn histplot and displot output doesn't match
p = sns.displot(data=data, x='age', stat='percent', hue='sex', height=4, common_norm=False)

p = sns.displot(data=data, x='age', stat='percent', col='sex', height=4, common_norm=False)

fig = plt.figure(figsize=(5, 4))
p = sns.histplot(data=data, x='age', stat='percent', hue='sex', common_norm=False)
plt.show()

相关文章