'Adding Percentage Labels to Grouper Bar Chart in Python with matplotlib?

I've been having trouble getting this to work successfully all day. Any help that anyone could offer would be immensely appreciated.

Essentially, I just need to add the value of each item in the Percentages list above each bar in the grouped bar chart that is produced with the attached code. I've tried ax.annotate and multiple other code options, but nothing seems to be working. Of course this is user error, but I'm unsure how to trouble shoot on my own.

Thanks so much for any help you can offer.

Here is the code I'm working with:

import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
import sys



Paid = [5858, 6351, 5111] 
Unpaid = [6917, 5738, 4006]
Percentages = [45.9, 54.1, 52.5, 47.5, 56.1, 43.9]

n=3
r = np.arange(n)
width = 0.25


plt.bar(r, Paid, color = 'b',
    width = width, edgecolor = 'black',
    label='Paid')


plt.bar(r + width, Unpaid, color = 'g',
    width = width, edgecolor = 'black',
    label='Unpaid')

plt.xlabel("Year")
plt.ylabel("Count")
plt.title("YOY Paid v. Unpaid WBL Opportunities")

plt.xticks(r + width/2,['2019-2020','2020-2021','2021-2022'])
plt.legend()
plt.show()


Solution 1:[1]

To remove the ambiguity about the bar labels, they should be written separately:

import pandas as pd
import numpy as np
import os
import matplotlib.pyplot as plt
import sys



Paid = [5858, 6351, 5111] 
Unpaid = [6917, 5738, 4006]
Paid_Percentages = [45.9, 52.5, 56.1]
Unpaid_Percentages = [54.1, 47.5, 43.9]

n=3
r = np.arange(n)
width = 0.25

fig, ax = plt.subplots()
rects1 = ax.bar(r, Paid, color = 'b', width = width, edgecolor = 'black', label='Paid')
rects2 = ax.bar(r + width, Unpaid, color = 'g', width = width, edgecolor = 'black', label='Unpaid')

plt.xlabel("Year")
plt.ylabel("Count")
plt.title("YOY Paid v. Unpaid WBL Opportunities")

plt.xticks(r + width/2,['2019-2020','2020-2021','2021-2022'])
plt.legend()

for rect,p in zip(rects1, Paid_Percentages):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width()/2, height+5, str(p)+'%', ha='center', va='bottom', fontsize=8, rotation=0, color='black')

for rect,p in zip(rects2, Unpaid_Percentages):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width()/2, height+5, str(p)+'%', ha='center', va='bottom', fontsize=8, rotation=0, color='black')

plt.show()

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1