1

I want to make a bar chart that has the absolute % on top of each bar.


The variables are all 'string' as below:

survey['What is the highest level of education you have completed?']
0       Undergraduate degree
1      Less than high school
2       High school graduate
3       Undergraduate degree
4             Masters degree
               ...          
529           Masters degree
530           Masters degree
531     Undergraduate degree
532     Undergraduate degree
533           Masters degree
Name: What is the highest level of education you have completed?, Length: 534, dtype: object

survey['agegroup']
0      Age 40 and above
1      Age 40 and above
2      Age 40 and above
3      Age 40 and above
4      Age 40 and above
             ...       
529        Age below 40
530        Age below 40
531    Age 40 and above
532    Age 40 and above
533        Age below 40
Name: agegroup, Length: 534, dtype: object

I have used the code below to make the chart to have count value on top of each bar, but I want to replace the count with absolute %:

`ax=sns.countplot(x=survey['What is the highest level of education you have completed?'].apply(lambda x:education[x]),
hue=survey['agegroup'],data=survey,palette="mako" )
ax.set_xlabel( 'What is the highest level of education you have completed?',fontsize = 14)
plt.legend(fontsize = 20)
plt.legend(loc='upper right')
for p in ax.patches:
    width = p.get_width()
    height = p.get_height()
    x, y = p.get_xy() 
    ax.annotate(f'{height}', (x + width/2, y + height*1.02), ha='center')`

The bar chart with count value


The % I want is absolute %, for example, the first bar should have the %=95/(95+18+91+47+10+8)

tdy
  • 36,675
  • 19
  • 86
  • 83

1 Answers1

0

for example, the first bar should have the %=95/(95+18+91+47+10+8)

In this case, you want the percentages per hue. Since each hue is stored as a container in ax.containers:

  1. Compute the within-hue ratios using the container's datavalues
  2. Label the bars using ax.bar_label (use the labels param to format the ratios into percentages)
for c in ax.containers:
    ratios = c.datavalues / c.datavalues.sum()
    ax.bar_label(c, labels=[f'{r:.1%}' for r in ratios]) # requires matplotlib 3.4+

new output

tdy
  • 36,675
  • 19
  • 86
  • 83