I can offer you this solution:
I have created a new DataFrame,df2, that contains the percentages that need to be painted.
The values of df2, have been ordered to correspond correctly with the index i that refers to the different bars.
This allows you to paint each value in the right place.
get_xy
obtains the x and y coordinates of the bottom corner of each bar.
get_width
gets the width of each bar.
get_height
gets the length of each bar.
To paint the percentages a loop is used. Each turn of a loop refers to a bar. The center of each bar is half the width and length. kx
and ky
are used to slightly correct the position.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline
data = [['M', 0], ['F', 0], ['M',1 ], ['M', 1], ['M', 1], ['F', 1], ['M', 0], ['M', 1], ['M', 0], ['F', 1], ['M', 0], ['M', 0]]
df = pd.DataFrame(data,columns=['Gender','label'])
F_Serie = df.groupby('Gender')['label'].value_counts()['F']
M_Serie = df.groupby('Gender')['label'].value_counts()['M']
M_Serie = M_Serie*(100/M_Serie.sum())
F_Serie = F_Serie*(100/F_Serie.sum())
df2 = pd.DataFrame(np.array([list(F_Serie), list(M_Serie)]), index = ['F', 'M'], columns = [0, 1])
ax = df.groupby('Gender')['label'].value_counts().unstack(level=1).plot.barh(stacked=True, figsize=(10, 6))
# Set txt
kx = -0.3
ky = -0.02
values = []
for key in df2.values:
values = values + list(key)
# ordering the values
val = values[1:3]
values.pop(1)
values.pop(1)
values = val + values
for i,rec in enumerate(ax.patches):
ax.text(rec.get_xy()[0]+rec.get_width()/2+kx,rec.get_xy()[1]+rec.get_height()/2+ky,'{:.1%}'.format(values[i]/100), fontsize=12, color='black')
