Plotting ax.bar_label on sns does not iterate through hue appropriately

Question:

I have this table

print(tmp.head())

  tumor_type tumor_or_normal           call  size    cancer_n     %
0        ACC           Tumor  Amplification     2    ACCnn=5  40.0
1        ACC           Tumor       Deletion     1    ACCnn=5  20.0
2        ACC           Tumor        Diploid     2    ACCnn=5  40.0
3       BLCA           Tumor  Amplification     3  BLCAnn=10  30.0
4       BLCA           Tumor       Deletion     1  BLCAnn=10  10.0

for which I am trying to add the size column values as bar labels:

plt.figure(figsize = (20,8))
palette = {'Amplification': 'red', 'Deletion': 'blue', 'Diploid': 'grey'}
ax = sns.barplot(x ="cancer_n", y = '%', data = tmp, hue = "call", palette=palette, alpha=0.7)
for container in ax.containers:
    ax.bar_label(container, labels=tmp['size'])
plt.show()

This uses the correct numbers but labels the bars incorrectly (labelling the first bar of each x-axis label instead of each bar of hue variable)

See here for the plot and error

How can I correct this?

Asked By: Nathan Tear

||

Answers:

The issue is that you give the whole size column for each hue. You need to provide the size values for ‘Amplification’, ‘Deletion’, and ‘Diploid’ separately.

plt.figure(figsize = (20,8))
palette = {'Amplification': 'red', 'Deletion': 'blue', 'Diploid': 'grey'}
ax = sns.barplot(x ="cancer_n", y = '%', data = tmp, hue = "call", palette=palette, alpha=0.7)
for container in ax.containers:
    tmp_hue = tmp.loc[tmp['call']==container.get_label()]
    ax.bar_label(container, labels=tmp_hue['size'])
plt.show()
Answered By: viggnah