如何用每个条形的总和(Matplotlib)注释堆积条形图? [英] How to annotate stacked bar chart with the sum of each bar (Matplotlib)?

查看:63
本文介绍了如何用每个条形的总和(Matplotlib)注释堆积条形图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分组条形图,每个条形都是堆叠的.

I have a grouped bar chart and each bar is stacked.

我已经用其单独的值注释了堆栈的每个部分,现在我想对这些值求和并注释每个条的总值(高度).我希望此注释位于每个条形图的顶部.

I have annotated each section of the stack with its individual value and now I would like to sum those values and annotate the total value(height) of each bar. I would like this annotation to be on top of each bar.

这是我正在使用的两个数据帧之一:

This is one of the two dataframes I am working from:

             df_title = pd.DataFrame(index=['F','M'], 
             data={'<10':[2.064897, 1.573255], '10-12':[3.933137, 4.326450], '13-17':[9.242871, 16.715831],
                    '18-24':[10.226155, 12.487709], '18-24':[8.161259, 10.717797], '35-44':[5.801377, 4.916421],
                    '45-54':[3.539823, 2.851524], '55+':[1.671583, 1.769912]})

在绘图之前,我将两个数据帧(df_title 和 df_comps)都转换为 numpy 数组.

I convert both dataframes (df_title and df_comps) into numpy arrays before plotting.

df_title_concat = np.concatenate((np.zeros((len,1)), df_title.T.values), axis=1)

完整代码如下:

    df_title 
    df_comps
    len  = df_title.shape[1]
    df_title_concat = np.concatenate((np.zeros((len,1)), df_title.T.values), axis=1)
    df_comps_concat = np.concatenate((np.zeros((len,1)), df_comps.T.values), axis=1)

    fig = plt.figure(figsize=(20,10))
    ax = plt.subplot()
    title_colors = ['skyblue', 'royalblue']
    comps_colors = ['lightgoldenrodyellow', 'orange']

    for i in range(1,3):
        for j in list(range(0, df_title.shape[1]-1)):
            j += 1 

            ax_1 = ax.bar(j, df_title_concat[j,i], width=-0.4, bottom=np.sum(df_title_concat[j,:i]), color = title_colors[i-1], 
                          edgecolor='black', linewidth=3, align='edge')

            for p in ax_1.patches:
                width, height = p.get_width(), p.get_height()
                x, y = p.get_xy() 
                if height > 2:
                    ax.annotate('{:.2f}%'.format(height), (p.get_x()+0.875*width, p.get_y()+.4*height), 
                                fontsize=16, fontweight='bold', color='black')

            ax_2 = ax.bar(j, df_comps_concat[j,i], width=0.4, bottom=np.sum(df_comps_concat[j,:i]), color = comps_colors[i-1], 
                          edgecolor='black', linewidth=3, align='edge')

            for p in ax_2.patches:
                width, height = p.get_width(), p.get_height()
                x, y = p.get_xy() 
                if height > 2:
                    ax.annotate('{:.2f}%'.format(height), (p.get_x()+0.15*width, p.get_y()+.4*height), 
                                fontsize=16, fontweight='bold', color='black')

推荐答案

这里有一个解决方案:

df_title = pd.DataFrame(index=['F','M'], 
             data={'<10':[2.064897, 1.573255], '10-12':[3.933137, 4.326450], '13-17':[9.242871, 16.715831],
                    '18-24':[10.226155, 12.487709], '18-24':[8.161259, 10.717797], '35-44':[5.801377, 4.916421],
                    '45-54':[3.539823, 2.851524], '55+':[1.671583, 1.769912]})


df_title_concat = np.concatenate((np.zeros((len(df_title),1)), df_title.T.values), axis=1)


fig = plt.figure(figsize=(12,8))
ax = plt.subplot()
title_colors = ['skyblue', 'royalblue']

for i in range(1,3):
    for j in list(range(0, df_title.shape[1]-1)):
        j += 1 
        bottom=np.sum(df_title_concat[j,:i])
        ax_1 = ax.bar(j, df_title_concat[j,i], width=-0.4, bottom=bottom, color = title_colors[i-1], 
                      edgecolor='black', linewidth=3, align='edge')

        for p in ax_1.patches:
            width, height = p.get_width(), p.get_height()
            if bottom != 0:
                ax.annotate('{:.2f}%'.format(height+bottom), (p.get_x()+0.875*width, (height+bottom)+0.3), 
                            fontsize=16, fontweight='bold', color='black')

但是,我建议您重新考虑您所遵循的整个方法并将情节更改为:

However, I would suggest you to rethink the whole approach you are following and change the plot to something like:

plt.bar(df_title.columns,df_title.loc['M'])
plt.bar(df_title.columns,df_title.loc['F'],bottom=df_title.loc['M'])

这篇关于如何用每个条形的总和(Matplotlib)注释堆积条形图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆