I want to display mean and standard deviation values above each of the boxplots in the grouped boxplot (see picture). 
My code is
import pandas as pd
import seaborn as sns
from os.path import expanduser as ospath
df = pd.read_excel(ospath('~/Documents/Python/Kandidatspeciale/TestData.xlsx'),'Ark1')
bp = sns.boxplot(y='throw angle', x='incident angle', 
                 data=df, 
                 palette="colorblind",
                 hue='Bat type')
bp.set_title('Rubber Comparison',fontsize=15,fontweight='bold', y=1.06)
bp.set_ylabel('Throw Angle [degrees]',fontsize=11.5)
bp.set_xlabel('Incident Angle [degrees]',fontsize=11.5)
Where my dataframe, df, is
    Bat type  incident angle  throw angle
0      euro              15         28.2
1      euro              15         27.5
2      euro              15         26.2
3      euro              15         27.7
4      euro              15         26.4
5      euro              15         29.0
6      euro              30         12.5
7      euro              30         14.7
8      euro              30         10.2
9     china              15         29.9
10    china              15         31.1
11    china              15         24.9
12    china              15         27.5
13    china              15         31.2
14    china              15         24.4
15    china              30          9.7
16    china              30          9.1
17    china              30          9.5
I tried with the following code. It needs to be independent of number of x (incident angles), for instance it should do the job for more angles of 45, 60 etc.
m=df.mean(axis=0) #Mean values 
st=df.std(axis=0) #Standard deviation values 
for i, line in enumerate(bp['medians']):
    x, y = line.get_xydata()[1]
    text = ' μ={:.2f}\n σ={:.2f}'.format(m[i], st[i])
    bp.annotate(text, xy=(x, y))
Can somebody help?
This question brought me here since I was also looking for a similar solution with seaborn.
After some trial and error, you just have to change the for loop to:
for i in range(len(m)):
    bp.annotate(
        ' μ={:.2f}\n σ={:.2f}'.format(m[i], st[i]), 
        xy=(i, m[i]), 
        horizontalalignment='center'
    )
This change worked for me (although I just wanted to print the actual median values). You can also add changes like the fontsize, color or style (i.e., weight) just by adding them as arguments in annotate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With