如何向条形图添加多个注释
Posted
技术标签:
【中文标题】如何向条形图添加多个注释【英文标题】:How to add multiple annotations to a barplot 【发布时间】:2020-08-26 07:27:36 【问题描述】:我想在我的 pandas barplot 中添加百分比值(除了计数)。但是,我无法这样做。我的代码如下所示,到目前为止,我可以获得要显示的计数值。有人可以帮我在每个条显示的计数值旁边/下方添加相对百分比值吗?
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();
我的代码的输出如下所示。如何在显示的每个计数值旁边添加 % 值?
【问题讨论】:
【参考方案1】:与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
从版本 3.4.2 开始使用 matplotlib
使用matplotlib.pyplot.bar_label
有关其他格式选项,请参阅 matplotlib: Bar Label Demo 页面。
使用pandas v1.2.4
测试,使用matplotlib
作为绘图引擎。
可以使用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 v3.4.2
Adding value labels on a matplotlib bar chart
How to annotate each segment of a stacked bar chart
Stacked Bar Chart with Centered Labels
How to plot and annotate multiple data columns in a seaborn barplot
How to annotate a seaborn barplot with the aggregated value
stack bar plot in matplotlib and add label to each section
How to plot and annotate a grouped bar chart
在 3.4.2 版本之前绘制使用 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()
你可以玩定位。
JohanC 提到的其他格式选项
将文本的两个部分打印在一个字符串中,并在其间加上\n
以获得“自然”的行间距:
str(f'round((y.get_width()), 1)\nround((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()
,当这些值达到数万时。
【讨论】:
对原始答案的精彩更新,特伦顿。谢谢! @sb2020 谢谢以上是关于如何向条形图添加多个注释的主要内容,如果未能解决你的问题,请参考以下文章