[英]How to add multiple annotations to a barplot
我想在我的 pandas 條形圖中添加百分比值 - 除了計數。 但是,我無法這樣做。 我的代碼如下所示,到目前為止,我可以獲得要顯示的計數值。 有人可以幫我在每個條顯示的計數值旁邊/下方添加相對百分比值嗎?
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
import seaborn as sns
sns.set_style("white")
fig = plt.figure()
fig.set_figheight(5)
fig.set_figwidth(10)
ax = fig.add_subplot(111)
counts = [29227, 102492, 53269, 504028, 802994]
y_ax = ('A','B','C','D','E')
y_tick = np.arange(len(y_ax))
ax.barh(range(len(counts)), counts, align = "center", color = "tab:blue")
ax.set_yticks(y_tick)
ax.set_yticklabels(y_ax, size = 8)
#annotate bar plot with values
for i in ax.patches:
ax.text(i.get_width()+.09, i.get_y()+.3, str(round((i.get_width()), 1)), fontsize=8)
sns.despine()
plt.show();
我的代碼的 output 如下所示。 如何在顯示的每個計數值旁邊添加 % 值?
pandas
pandas v1.2.4
測試import pandas as pd
import matplotlib.pyplot as plt
# create the dataframe from values in the OP
counts = [29227, 102492, 53269, 504028, 802994]
df = pd.DataFrame(data=counts, columns=['counts'], index=['A','B','C','D','E'])
# add a percent column
df['%'] = df.counts.div(df.counts.sum()).mul(100).round(2)
# display(df)
counts %
A 29227 1.96
B 102492 6.87
C 53269 3.57
D 504028 33.78
E 802994 53.82
matplotlib
matplotlib.pyplot.bar_label
.bar_label
的更多詳細信息和示例,請參閱如何在條形圖上添加值標簽。pandas v1.2.4
測試,使用matplotlib
作為 plot 引擎。fmt
參數完成,但更復雜的格式應該用labels
參數完成。ax = df.plot(kind='barh', y='counts', figsize=(10, 5), legend=False, width=.75,
title='This is the plot generated by all code examples in this answer')
# customize the label to include the percent
labels = [f' {v.get_width()}\n {df.iloc[i, 1]}%' for i, v in enumerate(ax.containers[0])]
# set the bar label
ax.bar_label(ax.containers[0], labels=labels, label_type='edge', size=13)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
matplotlib
# plot the dataframe
ax = df.plot(kind='barh', y='counts', figsize=(10, 5), legend=False, width=.75)
for i, y in enumerate(ax.patches):
# get the percent label
label_per = df.iloc[i, 1]
# add the value label
ax.text(y.get_width()+.09, y.get_y()+.3, str(round((y.get_width()), 1)), fontsize=10)
# add the percent label here
ax.text(y.get_width()+.09, y.get_y()+.1, str(f'{round((label_per), 2)}%'), fontsize=10)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
pandas
原始答案matplotlib v3.3.4
測試import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
counts = [29227, 102492, 53269, 504028, 802994]
# calculate percents
percents = [100*x/sum(counts) for x in counts]
y_ax = ('A','B','C','D','E')
y_tick = np.arange(len(y_ax))
ax.barh(range(len(counts)), counts, align = "center", color = "tab:blue")
ax.set_yticks(y_tick)
ax.set_yticklabels(y_ax, size = 8)
#annotate bar plot with values
for i, y in enumerate(ax.patches):
label_per = percents[i]
ax.text(y.get_width()+.09, y.get_y()+.3, str(round((y.get_width()), 1)), fontsize=10)
# add the percent label here
# ax.text(y.get_width()+.09, y.get_y()+.3, str(round((label_per), 2)), ha='right', va='center', fontsize=10)
ax.text(y.get_width()+.09, y.get_y()+.1, str(f'{round((label_per), 2)}%'), fontsize=10)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.show()
\n
以獲得“自然”行間距:str(f'{round((y.get_width()), 1)}\n{round((label_per), 2)}%')
ax.text(..., va='center')
垂直居中並能夠使用稍大的字體。ax.set_xlim(0, max(counts) * 1.18)
為文本獲得更多空間。str(f' {round((label_per), 2)}%')
,注意{
之前的空格。y.get_width()+.09
非常接近y.get_width()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.