【问题标题】:How to modify seaborn graph to have percentage information per class?如何修改 seaborn 图以获取每类的百分比信息?
【发布时间】:2022-01-12 01:24:44
【问题描述】:

我正在使用以下代码来绘制退货/未退货产品百分比(y 轴)相对于这些产品的折扣百分比(x 轴)。如果您看到,所有条形图都将增加到 100%。

sns.histplot(data=df_c, x='percent_discount_100', hue='returned',binwidth=10, stat='percent', ax=ax)
#ax.set_xlim(1,31)
#ax.set_xticks(range(0,100,10))
plt.show()

我想要更改每个条的百分比信息,我的意思是,对于每个条,我想添加退回和未退回的产品百分比(对于每个条,显然百分比将增加到 100%) .您能告诉我如何解决这个问题吗?

也可以添加使用其他库的解决方案,例如 plotly 和 matplotlib。

【问题讨论】:

标签: python matplotlib annotations seaborn histogram


【解决方案1】:

Seaborn 只是一种轻松探索数据的工具,并不完美。如果您想让图形可发布,请使用任何必要的工具。在您的情况下,pandas + matplotlib 是更好的选择。

如果没有给出数据,我假设你的数据是这样的(如果没有,就这样吧):

In [33]: df2 = pd.DataFrame(np.random.rand(10, 4), columns=["a", "b", "c", "d"])
In [34]: df2
Out[34]: 
          a         b         c         d
0  0.440042  0.509648  0.863190  0.532108
1  0.087648  0.695300  0.830660  0.468570
2  0.807494  0.195466  0.911627  0.278780
3  0.870929  0.971947  0.997894  0.780992
4  0.205380  0.097973  0.803379  0.100402
5  0.958186  0.362425  0.915435  0.585129
6  0.961905  0.196360  0.080999  0.933527
7  0.785202  0.497949  0.992512  0.518781
8  0.874882  0.610012  0.348986  0.996064
9  0.424615  0.135498  0.931710  0.619083

然后,将其转换为百分比,在df3 中,每行总和为1.0:

In [46]: df3 = df2.apply(lambda x: x / sum(x) * 100, axis=1)

In [47]: df3
Out[47]: 
           a          b          c          d
0  18.765234  21.733508  36.809987  22.691272
1   4.209449  33.392931  39.893775  22.503845
2  36.815260   8.911695  41.562896  12.710148
3  24.047114  26.836290  27.552722  21.563874
4  17.013872   8.116157  66.552564   8.317407
5  33.964091  12.846603  32.448702  20.740605
6  44.270478   9.037220   3.727897  42.964405
7  28.098676  17.819245  35.517338  18.564740
8  30.915164  21.555626  12.331912  35.197297
9  20.115278   6.418958  44.137918  29.327846

如果你只是想看看相对差异,

df3.plot.bar(stacked=True)

如果您想在条形上方添加百分比,请参阅How to display the value of the bar on each bar with pyplot.barh()

【讨论】:

    【解决方案2】:

    使用multiple='fill',条形将被拉伸以填充 100%。

    这是一个使用 Titanic 数据集的示例:

    from matplotlib import pyplot as plt
    from matplotlib.ticker import PercentFormatter
    import seaborn as sns
    
    titanic = sns.load_dataset('titanic')
    fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 4))
    for ax, multiple in zip((ax1, ax2), ['layer', 'fill']):
        sns.histplot(data=titanic, x='age', hue='sex', binwidth=10, stat='percent', multiple=multiple, ax=ax)
        ax.set_title(f"multiple='{multiple}'")
    # ax.bar_label(ax.containers[0], fmt='%.2f',label_type='center', color='black')
    # ax.bar_label(ax.containers[1], fmt='%.2f', label_type='center', color='white')
    for bar_group, color in zip(ax.containers, ['black', 'white']):
        ax.bar_label(bar_group, label_type='center', color=color,
                     labels=[f'{bar.get_height() * 100:.1f} %' if bar.get_height() > 0 else '' for bar in bar_group])
    ax.yaxis.set_major_formatter(PercentFormatter(1))
    plt.tight_layout()
    plt.show()
    

    【讨论】:

    • 谢谢,这就是我要找的答案。
    • 如果这回答了您的问题,您可以考虑将答案标记为已接受
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2018-02-18
    相关资源
    最近更新 更多