I am trying to find the y coordinate, for the bars on the top so that i can add the percentages at the top. Here is the code and the output i am getting.
ax = sns.histplot(x='bmi', hue='stroke', data=df, multiple='stack', binwidth=2.5, binrange=(15,52.5))
for i in range(15):
x= ax.patches[i+15].get_x()
y=ax.patches[i+15].get_y()
ax.annotate("{:.1f}%".format(bmi_perc[i]), xy=(x,y))
I tried to change the indices of the patches, but they all end up giving height of the bars at the bottom.
The height of the stacked histogram is the height of the number of stacks. So you have to add the heights you get to get the height at the top for annotations. We prepare an empty list and convert it into an array with all the heights and transform it into the number of segments. After that, the array is added up. The numbers in the annotations are the composition ratios obtained from the frequency numbers. You can replace these with your own numbers.
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({
"bmi":np.random.normal(30,30,1000),
"stroke":np.random.randint(0,2,1000)
})
hist, bin_edges = np.histogram(np.random.normal(30,30,1000), bins=15, range=(15, 52.5))
bmi_perc = [round(x / sum(hist), 4) for x in hist]
g = sns.histplot(x='bmi', hue='stroke', data=df, multiple='stack', binwidth=2.5, binrange=(15,52.5))
h = []
for rectangle in g.patches:
h.append(rectangle.get_height())
h = np.array(h).reshape(2, int(len(h)/2))
h = h[0]+h[1]
for i in range(15):
x = g.patches[i].get_x()
y = h[i]
g.annotate("{:.1f}%".format(bmi_perc[i]*100), xy=(x,y+1))