使用Matplotlib和Pandas注释堆叠条形图

10

我是一位有用的助手,可以为您进行翻译。

我有一个简单的数据框,存储了一项调查的结果。列包括:

| Age | Income | Satisfaction |

它们都包含 15(分类)之间的值。我成功生成了一个堆叠条形图,显示了不同年龄段人群中 Satisfaction 值的分布情况。 代码如下:

#create a random df
data = []
for i in range(500):
    sample = {"age" : random.randint(0,5), "income" : random.randint(1,5), "satisfaction" : random.randint(1,5)}
data.append(sample)
df = pd.DataFrame(data)
#group by age
counter = df.groupby('age')['satisfaction'].value_counts().unstack()
#calculate the % for each age group 
percentage_dist = 100 * counter.divide(counter.sum(axis = 1), axis = 0)
percentage_dist.plot.bar(stacked=True)

这将生成以下所需的图表: enter image description here 然而,如果要比较Age-0green子集(百分比)是否高于Age-2中的子集,则会很困难。因此,有没有一种方法可以在每个条形图的子部分上方添加百分比。类似于这样,但是对于每个单独的条形图: enter image description here
1个回答

37

一种选择是迭代遍历补丁,以获得它们的宽度、高度和左下角坐标,并使用这些值将标签放置在相应条形图的中心。

为了实现这一点,必须存储由Pandas bar方法返回的轴。

ax = percentage_dist.plot.bar(stacked=True)
for p in ax.patches:
    width, height = p.get_width(), p.get_height()
    x, y = p.get_xy() 
    ax.text(x+width/2, 
            y+height/2, 
            '{:.0f} %'.format(height), 
            horizontalalignment='center', 
            verticalalignment='center')

这里,注释值设置为0小数位, 但这可以很容易地进行修改。

使用此代码生成的输出图如下:

输入图像描述


1
这对我来说是最好的答案,包括链接的帖子。为了处理堆栈中不存在类别的情况(在底部产生异常的0%标签),我添加了: continue``` - flashliquid
很高兴能帮上忙!实际上我并没有太多想过这个答案,我已经进行了编辑以改进标签的放置位置,现在它们是居中的了。 - OriolAbril
1
你也可以将数字的格式更改为{:.0%}。 - Guy
2
使用这种方法,当每列高度不同时(列补丁不加起来为100 - 不代表百分比),您将如何计算百分比? - Daniel Kats
我能够通过枚举补丁,然后使用索引来索引类别来完成这个操作。但是这种方法并不感觉很干净... - Daniel Kats

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接