I have this example of violin plot, but i want to customize the inner box, for example instead of medians to show the means, the whiskers instead of quartiles to show the mean +/- sd , change the color of the mean line for example, I tried different mean but I can't do it .
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_style('white')
tips = sns.load_dataset('tips')
palette = sns.cubehelix_palette(start=.5, rot=-.5, dark=0.3, light=0.7)
ax = sns.violinplot(y="day", x="total_bill", data=tips,palette=palette,scale="width", inner="box")
plt.show()
I tried different things, for example the inner arguments of the plots, but I got many errors messages.
The main properties that can be changed for the box plot for sns.violinplot(..., inner='box')
as of Seaborn 0.13.2 are the following. Note that a simplified boxplot is used, with a marker for the median, a thicker line between Q1 and Q3, and a thin line between the whiskers
If you need a more complicated boxplot, you can set inner=None
and draw boxplots on top of the violins.
You seem to want to draw a non-standard boxplot, with the mean and standard deviation. As boxplots have a generally accepted definition, the positions of the box and the whiskers have an expected meaning for most people viewing the plot. As such, a different position isn't recommended.
If you really need to work with mean and standard deviation, you can use matplotlib to draw them on top of the violins. Here is an example:
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset('tips')
# make sure the groupby column is categorical, to have the same order as the y-values
tips['day'] = tips['day'].astype('category')
fig, ax = plt.subplots(figsize=(7, 5))
palette = sns.cubehelix_palette(start=.5, rot=-.5, dark=0.3, light=0.7,
n_colors=len(tips['day'].cat.categories))
sns.violinplot(tips, x='total_bill', y='day', hue='day', bw_adjust=0.5,
palette=palette, saturation=1, inner=None, ax=ax)
for i, (day, df1) in enumerate(tips.groupby('day', observed=True)['total_bill']):
mean = df1.mean()
sd = df1.std()
# ax.vlines([df1.min(), mean - sd, mean, mean + sd, df1.max()], i - 0.45, i + 0.45,
# color='black', ls=[':', '--', '-', '--', ':'], lw=2)
# thin bar between min and max
ax.errorbar(y=day, x=mean, xerr=[[mean - df1.min()], [df1.max() - mean]], color='yellow', lw=2)
# thicker bar between mean +/- sd, mean in red, rombo shaped
ax.errorbar(y=day, x=mean, xerr=sd, color='yellow', lw=10,
mec='r', mfc='r', marker='D', ms=8)
sns.despine()
plt.tight_layout()
plt.show()