亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何向堆積百分比條形圖添加注釋

如何向堆積百分比條形圖添加注釋

長風秋雁 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條經驗 獲得超2個贊

  • 可以通過從 中提取條形位置來注釋條形圖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 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號