【问题标题】:Is there a way I can get the total of a hue seaborn bar graph countplot to total 100% per hue bar?有没有一种方法可以让色调 seaborn 条形图计数图的总数达到每个色调条的 100%?
【发布时间】:2020-01-05 08:17:46
【问题描述】:

我有一个 seaborn 计数图,其中包含了“色调参数”,这就是绘图的样子:

男性总人数 = 240 669,活跃男性总人数 = 130 856,流失男性总人数 = 109 813

M(活跃)--- 130856/240669 = 54.4% 和 M(流失)--- 109813/240669 =45.6%

女性

女性总人数 = 198 408,活跃女性总人数 = 111 107,流失女性总人数 = 87 301

所以 F(活跃)--- 111107/198408 = 56% 和 F(流失)--- 87301/198408 =44%

我希望每个性别的总百分比为 100%,而不是附图中给出的百分比。

这是我使用的代码:

plt.figure(figsize=(10,6))
colours = ['b','red']
ax = sns.countplot(df.GENDER,hue=df['Status'],order = 
df['GENDER'].value_counts().index,palette=colours)
plt.title("GENDER VS STATUS",fontsize=15)
plt.tight_layout()


plt.xticks(fontsize=14)
plt.yticks(fontsize=14)

total = float(len(df))
for p in ax.patches:
    height = p.get_height()
    ax.text(p.get_x()+p.get_width()/2.,
        height + 3,
        '{0:.1%}'.format(height/total),
        ha="center", fontsize=15)



print(df['GENDER'].value_counts(normalize=True))

【问题讨论】:

    标签: python-3.x matplotlib seaborn


    【解决方案1】:

    在您的注释循环中,您必须将高度除以 M/F 的总数。请记住,countplot 绘制按 hues 分组的补丁。也就是说,补丁列表将交错M hue1 / F hue1 / M hue2 / F hue2,因此您可以将总数计算为`[total M,total F,total M,total F]并循环遍历与您的补丁同时进行:

    colours = ['b','red']
    totals = df['GENDER'].value_counts()
    n_hues = df['Status'].unique().size
    ax = sns.countplot(df.GENDER,hue=df['Status'],order=totals.index,palette=colours)
    plt.title("GENDER VS STATUS",fontsize=15)
    plt.tight_layout()
    
    
    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)
    
    temp_totals = totals.values.tolist()*n_hues
    for p,t in zip(ax.patches,temp_totals):
        height = p.get_height()
        ax.text(p.get_x()+p.get_width()/2.,
            height + 3,
            '{0:.1%}'.format(height/t),
            ha="center", fontsize=15)
    

    【讨论】:

    • “通过反复试验”并不是很有用。只要你不专门设置hue_order,它可能是相反的。
    • @ImportanceOfBeingErnest 在我看来,对于这种情况,我们只需要知道指定的order;我只是想说补丁不一定按照屏幕上绘制的顺序返回(最初这是我的一个愚蠢的假设)
    • 好的,所以这句话实际上与答案无关。很抱歉造成混乱。
    【解决方案2】:

    我总是发现将数据聚合和绘图分开更容易。所以我建议首先计算你需要的所有值,然后从中绘制一个条形图。 (这里不需要 seaborn。)

    import matplotlib.pyplot as plt
    import pandas as pd
    
    df = pd.DataFrame({"gender" : list("MMMMFFFFFF"),
                       "category" : list("BAABABBAAA")})
    
    piv = df.groupby(["gender", "category"]).size().unstack("category")
    grouped_perc = (piv.T / piv.sum(axis=0).values).T
    
    ax = piv.plot.bar()
    for bar, val in zip(ax.patches, grouped_perc.T.values.flat):
        ax.annotate('{0:.1%}'.format(val), 
                    xy=(bar.get_x()+bar.get_width()/2., bar.get_height()),
                    xytext=(0,5), textcoords="offset points", ha="center")
    
    ax.margins(y=0.1)
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2017-09-12
      • 2016-05-15
      • 2023-03-29
      • 2018-10-16
      • 1970-01-01
      • 2018-09-20
      • 2018-10-23
      • 2017-12-05
      • 2022-01-20
      相关资源
      最近更新 更多