I want to add percentage on the top of bars according to the hue. That means all the red and blue bars are equal to 100% respectively.
I can make the blue bars equal to 100%, but the red bars can't. Which parts should be modified?
Imports and Sample Data
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# sample data
np.random.seed(365)
rows = 100000
data = {'Call_ID': np.random.normal(10000, 8000, size=rows).astype(int),
'with_client_nmbr': np.random.choice([False, True], size=rows, p=[.17, .83]),
'Type_of_Caller': np.random.choice(['Agency', 'EE', 'ER'], size=rows, p=[.06, .77, .17])}
all_call = pd.DataFrame(data)
Call_ID with_client_nmbr Type_of_Caller
0 11343 True EE
1 14188 True Agency
2 16539 False EE
3 23630 True ER
4 -7175 True EE
Aggregate and Plot
df_agg= all_call.groupby(['Type_of_Caller','with_client_nmbr'])['Call_ID'].nunique().reset_index()
ax = sns.barplot(x='Type_of_Caller', y='Call_ID', hue='with_client_nmbr',
data=df_agg,palette=['orangered', 'skyblue'])
hue_order = all_call['with_client_nmbr'].unique()
df_f = sum(all_call.query("with_client_nmbr==False").groupby('Type_of_Caller')['Call_ID'].nunique())
df_t = sum(all_call.query("with_client_nmbr==True").groupby('Type_of_Caller')['Call_ID'].nunique())
for bars in ax.containers:
if bars.get_label() == hue_order[0]:
group_total = df_f
else:
group_total = df_t
for p in ax.patches:
width = p.get_width()
height = p.get_height()
x, y = p.get_xy()
ax.annotate(f'{(height/group_total):.1%}', (x + width/2, y + height*1.02), ha='center')
plt.show()
print(hue_order)
is['False', 'True']