按色调组调整seaborn计数图

问题描述

我有一个看起来像这样的数据集

状态 age_group
失败 18-25
失败 26-30
失败 18-25
成功 41-50

等等...

sns.countplot(y='status',hue='age_group',data=data)

当我计算完整数据集时,我得到了这个 dataset countplot hued by age_group

问题如下,如何直接用seaborn绘制由每个age_group的出现次数调整的图?因为没有它,该图确实具有误导性,例如,60 岁以上的年龄组看起来最简单,因为该年龄组中有更多人。我搜索了文档,但它没有针对这种情况的任何内置功能

提前致谢。

解决方法

显示比例的最简单方法是通过 sns.histogram(...,multiple='fill')。要强制按年龄组和状态排序,创建有序类别会有所帮助。

这是一些示例代码,使用 seaborn 0.11.1 测试:

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

data = pd.DataFrame({'status': np.random.choice(['Success','Failure'],100,p=[.7,.3]),'age_group': np.random.choice(['18-45','45-60','> 60'],p=[.2,.3,.5])})
data['age_group'] = pd.Categorical(data['age_group'],ordered=True,categories=['18-45','> 60'])
data['status'] = pd.Categorical(data['status'],categories=['Failure','Success'])
ax = sns.histplot(y='age_group',hue='status',multiple='fill',data=data)
ax.xaxis.set_major_formatter(PercentFormatter(1))
ax.set_xlabel('Percentage')
plt.show()

histplot with multiple='fill'

现在,为了创建问题的确切情节,一些熊猫操作可能会创建以下数据框:

  • 计算每个年龄组和状态的值
  • 将这些除以每个年龄段的总数

也许可以采取一些捷径,但这就是我尝试与熊猫玩杂耍的方式(从@PatrickFitzGerald 的评论中编辑:使用pd.crosstab()):

# df = data.groupby(['status','age_group']).agg(len).reset_index(level=0) \
#     .pivot(columns='status').droplevel(level=0,axis=1)
# totals = df.sum(axis=1)
# df['Success'] /= totals
# df['Failure'] /= totals
df = pd.crosstab(data['age_group'],data['status'],normalize='index')
df1 = df.melt(var_name='status',value_name='percentage',ignore_index=False).reset_index()
ax = sns.barplot(y='status',x='percentage',hue='age_group',palette='rocket',data=df1)
ax.xaxis.set_major_formatter(PercentFormatter(1))
ax.set_xlabel('Percentage')
ax.set_ylabel('')
plt.show()

procentual barplot