【问题标题】:How to plot stacked 100% bar plot with seaborn for categorical data如何使用 seaborn 为分类数据绘制堆叠 100% 条形图
【发布时间】:2021-12-19 03:13:28
【问题描述】:

我有一个如下所示的数据集(假设 Clicked 中有 4 个类别,head(10) 仅显示 2 个类别):

    Rank Clicked
0   2.0 Cat4
1   2.0 Cat4
2   2.0 Cat4
3   1.0 Cat1
4   1.0 Cat4
5   2.0 Cat4
6   2.0 Cat4
7   3.0 Cat4
8   5.0 Cat4
9   5.0 Cat4

这是返回此图的代码:

eee = (df.groupby(['Rank','Clicked'])['Clicked'].count()/df.groupby(['Rank'])['Clicked'].count())
eee.unstack().plot.bar(stacked=True)
plt.legend(['Cat1','Cat2','Cat3','Cat4'])
plt.xlabel('Rank')

有没有办法使用 seaborn(或 matplotlib)而不是 pandas 绘图功能来实现这一点?我尝试了几种方法,运行 seaborn 代码和预处理数据集,使其格式正确,但没有成功。

【问题讨论】:

  • Seaborn 只是 matplotlib 的一个 api,pandas 正在使用 matplotlib。 pandas 有堆叠条,seaborn 没有。使用ggplot styles in Python,就是风格的区别。
  • 应该是df.groupby(['Rank'])['Clicked'].value_counts(normalize=True).unstack().plot(kind='bar', stacked=True)
  • Groupby 应该使用 value_counts 进行标准化:How to create a groupby dataframe without a multi-level index
  • 您可以使用每个 seaborn 参数列表末尾的 **kwargs 将任何内容传递给底层的 matplotlib 调用。但!我经常需要阅读 seaborn 代码来弄清楚如何做到这一点,并且找到 matplotlib 的样式选项会更容易。

标签: python pandas matplotlib plot seaborn


【解决方案1】:

例如

tips = sns.load_dataset("tips")
sns.histplot(
    data=tips,
    x="size", hue="day",
    multiple="fill", stat="proportion",
    discrete=True, shrink=.8
)

【讨论】:

    【解决方案2】:

    Seaborn 不支持堆积条形图,所以需要绘制 cumsum:

    # calculate the distribution of `Clicked` per `Rank`
    distribution = pd.crosstab(df.Rank, df.Clicked, normalize='index')
    
    # plot the cumsum, with reverse hue order
    sns.barplot(data=distribution.cumsum(axis=1).stack().reset_index(name='Dist'),
                x='Rank', y='Dist', hue='Clicked',
                hue_order = distribution.columns[::-1],   # reverse hue order so that the taller bars got plotted first
                dodge=False)
    

    输出:

    最好也可以反转cumsum方向,这样就不需要反转hue order了:

    sns.barplot(data=distribution.iloc[:,::-1].cumsum(axis=1)       # we reverse cumsum direction here
                           .stack().reset_index(name='Dist'),
                x='Rank', y='Dist', hue='Clicked',
                hue_order=distribution.columns,                     # forward order
                dodge=False)
    

    输出:

    【讨论】:

    • 我不知道为什么有人对你的答案投了反对票……这真的很好!我确实有一个问题:我怎样才能给出自定义的 hue_order,例如:Cat2、Cat4、Cat1、Cat3?尝试将其作为列表传递,但它不接受它
    猜你喜欢
    • 2022-08-03
    • 2019-07-29
    • 2021-06-18
    • 2020-09-24
    • 1970-01-01
    • 2023-03-11
    • 2022-01-16
    • 2021-07-28
    相关资源
    最近更新 更多