如何修改 seaborn 图以获取每类的百分比信息?
Posted
技术标签:
【中文标题】如何修改 seaborn 图以获取每类的百分比信息?【英文标题】:How to modify seaborn graph to have percentage information per class? 【发布时间】: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。
【问题讨论】:
这能回答你的问题吗? How to annotate barplot with percent by hue/legend group 和How to add percentages on top of bars in seaborn 和How to plot percentage with seaborn distplot / histplot / displot @TrentonMcKinney 不是真的,我希望每个条添加到 100%,返回和未返回描述它们的百分比(例如,第一个条可能有 10% 的返回和 90% 的未返回) ,所以在某种程度上,我认为所有条形都可以具有相同的高度,只是返回和未返回的比例不同。 这个问题需要SSCCE。请参阅How to ask a good question。始终提供完整的minimal reproducible example,其中包含代码、数据、错误、当前输出和预期输出,如formatted text。如果相关,只有绘图图像是可以的。如果您不包含 mre,则该问题可能会被否决、关闭和删除。 我的 x 轴也没有分类变量:没关系。.bar_label
可以正常工作,因为这些是标签,而不是条形的实际位置,如 如何使用 seaborn distplot / histplot / displot 绘制百分比中所示
【参考方案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()
【讨论】:
谢谢,这就是我要找的答案。 如果这回答了您的问题,您可以考虑将答案标记为已接受以上是关于如何修改 seaborn 图以获取每类的百分比信息?的主要内容,如果未能解决你的问题,请参考以下文章
Seaborn:如何在绘图的 X 轴上的每个值之后添加一个“%”符号,而不是将值转换为百分比? [复制]