I have this dataframe
rules count percentage groups weight
A 15 24% 1 10
B 5 2% 2 30
C 25 50% 3 50
I have the following code:
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")
and I get the following error when trying to annotate the barchart with the percentage.
Inside the barchart is another number corresponding to the weight column in the 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
CodePudding user response:
- As of
- Annotation with two custom labels (
'weight'
and'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)
- The issue with the existing code is there are 9 patches, as can be seen with
print(patches)
orlist(patches)
, which can be resolved by selecting only the patches with a height greater than 0.- This occurs because
hue
is being used, but there is only one value in'groups'
for each value in'rules'
.
- This occurs because
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")
- Annotation with two custom labels (