如何向条形图添加多个注释 [英] How to add multiple annotations to a barplot
本文介绍了如何向条形图添加多个注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想将百分比值 - 除了计数 - 添加到我的 Pandas 条形图中.但是,我无法这样做.我的代码如下所示,到目前为止,我可以获得要显示的计数值.有人可以帮我在每个条形显示的计数值旁边/下方添加相对百分比值吗?
I would like to add percent values - in addition to counts - to my pandas barplot. However, I am not able to do so. My code is shown below and thus far I can get count values to display. Can somebody please help me add relative % values next to/below the count values displayed for each bar?
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();
我的代码的输出如下所示.如何在显示的每个计数值旁边添加 % 值?
The output of my code is shown below. How can one add % values next to each count value displayed?
推荐答案
With 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:条形标签演示页面.
- 使用
pandas v1.2.4
进行测试,使用matplotlib
作为绘图引擎. - 一些格式化可以使用
fmt
参数完成,但更复杂的格式化应该使用labels
参数完成. - Use
matplotlib.pyplot.bar_label
- See the matplotlib: Bar Label Demo page for additional formatting options.
- Tested with
pandas v1.2.4
, which is usingmatplotlib
as the plot engine. - Some formatting can be done with the
fmt
parameter, but more sophisticated formatting should be done with thelabels
parameter.
Plot use matplotlib
from version 3.4.2
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()}
{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 条形图上添加值标签
- 如何注释堆积条形图的每一段
- 带有居中标签的堆积条形图
- 如何在 seaborn 条形图中绘制和注释多个数据列
- 如何使用聚合值注释 seaborn 条形图
- 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
进行测试 - Tested with
matplotlib v3.3.4
Original Answer without pandas
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 提到的其他格式选项
- 在一个字符串中打印文本的两个部分,中间有一个
str(f'{round((y.get_width()), 1)} {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()
当这些值数以万计时.- You can play with the positioning.
- Other formatting options mentioned by JohanC
- Print both parts of the text in one string with a
str(f'{round((y.get_width()), 1)} {round((label_per), 2)}%')
ax.text(..., va='center')
to vertically center and be able to use a slightly larger font.ax.set_xlim(0, max(counts) * 1.18)
to get a bit more space for the text.- Start each line of text with a space to get a natural "horizontal" padding.
str(f' {round((label_per), 2)}%')
, note the space before{
.y.get_width()+.09
is extremely close toy.get_width()
when these values are in the tens of thousands.
这篇关于如何向条形图添加多个注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文