我有这个数据框
rules count percentage groups weight
A 15 24% 1 10
B 5 2% 2 30
C 25 50% 3 50
我有以下代码:
sns.set(rc={'figure.figsize':(18,9.5)})
plots = sns.barplot(x="rules", y="count", data=df, hue=df['groups'], dodge=False)
percentage = df['percentage'].tolist()
weight = df['weight'].tolist()
patches = plots.patches
for i in range(len(patches)):
x = patches[i].get_x() + patches[i].get_width()/2
y = patches[i].get_height()+.09
plots.annotate('{:.1f}%'.format(percentage[i]), (x, y), ha='center', va='bottom', size=14)
plots.annotate('{:.0f}'.format(weight[i]), (x, y), ha='center', va='top', color='white', size=15, fontweight="bold")
尝试用百分比注释条形图时出现以下错误。
条形图中是另一个数字,对应于 df 中的权重列。
IndexError Traceback (most recent call last)
<ipython-input-120-0ef14f891711> in <module>()
7 x = patches[i].get_x() + patches[i].get_width()/2
8 y = patches[i].get_height()+.09
----> 9 plots.annotate('{:.1f}%'.format(percentage[i]), (x, y), ha='center', va='bottom', size=14)
10 plots.annotate('{:.0f}'.format(weight[i]), (x, y), ha='center', va='top', color='white', size=15, fontweight="bold")
11 plots.set_xticklabels(plots.get_xticklabels(), rotation=90, fontsize=15)
IndexError: list index out of range
最佳答案
- 截至
matplotlib 3.4.0
最好使用matplotlib.pyplot.bar_label
,如 How to add value labels on a bar chart 中所述。但是,该答案并未解释如何获取这两个注释。 - 在
python 3.10
、pandas 1.4.2
、matplotlib 3.5.1
、seaborn 0.11.2<中测试
import pandas as pd
import seaborn as sns
# test data
data = {'rules': ['A', 'B', 'C'], 'count': [15, 5, 25],
'percentage': ['24%', '2%', '50%'], 'groups': [1, 2, 3], 'weight': [10, 30, 50]}
df = pd.DataFrame(data)
# plot
ax = sns.barplot(x="rules", y="count", data=df, hue='groups', dodge=False)
# since you are using hue, there are multiple containers
for c in ax.containers:
# set the bar label based on the y-axis
ax.bar_label(c, label_type='center', padding=1)
# add an annotations with custom labels
ax.bar_label(c, labels=df.percentage, label_type='edge', padding=1)
# pad the spacing between the number and the edge of the figure
ax.margins(y=0.1)
- 带有两个自定义标签的注释(
'weight'
和'percentage'
)。
ax = sns.barplot(x="rules", y="count", data=df, hue='groups', dodge=False)
# since you are using hue, there are multiple containers
for c in ax.containers:
# add an annotations with custom labels
ax.bar_label(c, labels=df.weight, label_type='center')
# add an annotations with custom labels
ax.bar_label(c, labels=df.percentage, label_type='edge', padding=1)
ax.margins(y=0.1)
- 现有代码的问题是有 9 个补丁,如
print(patches)
或list(patches)
所示,可以通过选择解决仅高度大于 0 的补丁。- 出现这种情况是因为正在使用
hue
,但对于'rules'
中的每个值,'groups'
中只有一个值。
- 出现这种情况是因为正在使用
plots = sns.barplot(x="rules", y="count", data=df, hue=df['groups'], dodge=False)
percentage = df['percentage'].tolist()
weight = df['weight'].tolist()
patches = plots.patches
# select patches with a height > 0
patches = [p for p in patches if p.get_height() > 0]
for i, p in enumerate(patches):
x = p.get_x() + patches[i].get_width()/2
y = p.get_height()+.09
plots.annotate(f'{percentage[i]}', (x, y), ha='center', va='bottom', size=14)
plots.annotate(f'{weight[i]:.0f}', (x, y), ha='center', va='top', color='white', size=15, fontweight="bold")
关于python - 如何使用多个自定义值标记条形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72970649/