为了账号安全,请及时绑定邮箱和手机立即绑定

如何向堆积百分比条形图添加注释

如何向堆积百分比条形图添加注释

长风秋雁 2023-08-08 09:53:01
我想使用 matplotlib 将值添加到堆积条形图。到目前为止,我已经能够创建堆积条形图,但我对如何添加注释感到困惑。我想要一个类似的输出,而不是整个图表,而只是中间的注释。import pandas as pdimport seaborn as snsimport matplotlib.pyplot as pltdata = {'Range':['<10','>10', '>= 20', '<10','>10', '>= 20', '<10','>10', '>= 20'],    'Price':[50,25,25,70,20,10,80,10,10]    'Value':[100,50,50,140,40,20,160,20,20]}    df1 = pd.DataFrame(data)b1 = df1[(df1['Range'] == '<10']['Price']b2 = df1[df1['Range'] == '>10']['Price']b3 = df1[df1['Range'] == '>= 20']['Price']totals = [i+j+k for i,j,k in zip(b1,b2,b3)]greenBars = [i / j * 100 for i,j in zip(b1, totals)]orangeBars = [i / j * 100 for i,j in zip(b2, totals)]blueBars = [i / j * 100 for i,j in zip(b3, totals)]barWidth = 0.5names = ('low', 'medium', 'high')r = [0,1,2]plt.bar(r, greenBars, color='#b5ffb9', edgecolor='white', width=barWidth, label = '$<10')plt.bar(r, orangeBars, bottom=greenBars, color='#f9bc86', edgecolor='white', width=barWidth, label = '$>10')plt.bar(r, blueBars, bottom=[i+j for i,j in zip(greenBars, orangeBars)], color='#a3acff', edgecolor='white', width=barWidth, label = '$>=20')plt.xticks(r, names)plt.xlabel("group")plt.legend(loc='upper left', bbox_to_anchor=(1,1), ncol=1)plt.show()添加了上面的代码来创建堆积图。期望的输出:对于低类别,通过从列中提取值Value(100、50 和 50)在堆栈上添加注释对于中值,值为 140、40 和 20。对于高值,值为 160、20 和 20。
查看完整描述

1 回答

?
DIEA

TA贡献1820条经验 获得超3个赞

  • 可以通过从 中提取条形位置来注释条形图ax.patches

    • 补丁数据不包含与数据帧相对应的标签,因此关联不同的数据值集成为一个定制过程。

  • 为了用Value代替进行注释Price,需要有一种方法来关联相应的值。

    • 字典不起作用,因为有重复值

    • 为 制作一个旋转数据框Value和 的相应数据框Price。这将确保相应的数据位于同一位置。

  • col_idxrow_idx将与 一起使用.iloc来查找 中的正确值df_value,并用它来注释绘图。

    • col_idxrow_idx都可以在 中重置或更新if i%3 == 0,因为有 3 个条和 3 个段,但是,如果条和段的数量不同,则需要不同的重置条件。

import pandas as pd

import matplotlib.pyplot as plt


# create the dataframe

data = {'Range':['<10','>10', '>= 20', '<10','>10', '>= 20', '<10','>10', '>= 20'],

        'Price':[50,25,25,70,20,10,80,10,10],

        'Value':[100,50,50,140,40,20,160,20,20]}    


df1 = pd.DataFrame(data)


# pivot the price data

df_price = df1.assign(idx=df1.groupby('Range').cumcount()).pivot(index='idx', columns='Range', values='Price')


Range  <10  >10  >= 20

idx                   

0       50   25     25

1       70   20     10

2       80   10     10


# pivot the value data

df_value = df1.assign(idx=df1.groupby('Range').cumcount()).pivot(index='idx', columns='Range', values='Value')


Range  <10  >10  >= 20

idx                   

0      100   50     50

1      140   40     20

2      160   20     20


# set colors

colors = ['#b5ffb9', '#f9bc86', '#a3acff']


# plot the price

ax = df_price.plot.bar(stacked=True, figsize=(8, 6), color=colors, ec='w')


# label the x-axis

plt.xticks(ticks=range(3), labels=['low', 'med', 'high'], rotation=0)


# x-axis title

plt.xlabel('group')


# position the legend

plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')


# annotate the bar segments

# col and row iloc indices for df_value

col_idx = 0

row_idx = 0


# iterate through each bar patch from ax

for i, p in enumerate(ax.patches, 1):


    left, bottom, width, height = p.get_bbox().bounds

    v = df_value.iloc[row_idx, col_idx]

    if width > 0:

        ax.annotate(f'{v:0.0f}', xy=(left+width/2, bottom+height/2), ha='center', va='center')


        # use this line to add commas for thousands

#        ax.annotate(f'{v:,}', xy=(left+width/2, bottom+height/2), ha='center', va='center')

    

    row_idx += 1

    if i%3 == 0:  # there are three bars, so update the indices 

        col_idx += 1

        row_idx = 0

https://img4.sycdn.imooc.com/64d1a0270001366705820368.jpg

查看完整回答
反对 回复 2023-08-08
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号