我在这里发布我的最终解决方案。我一开始想做这种绘图的原因是为了在同一个图中显示分布形状、均值变化和异常值的信息。通过 mwaskom 的指针和其他一些调整,我终于得到了我想要的东西。
左手图是与所有数据点绘制成线的比较,右手图是我的最终图。小提琴中间的粗灰色线是均值的自举 99% 置信区间,即白色水平线,均来自点图。三条虚线是标准的第 25、50 和 75 个百分位数,外面的线是我在小提琴图顶部绘制的箱线图的胡须帽。单个数据点被绘制为超出该点的线,因为我的数据通常有一些极端的数据,我需要手动删除,就像下面小提琴中的两个点一样。
目前,除了这些增强的小提琴,我将继续制作直方图和箱线图,但我希望发现所有信息都准确地捕获在小提琴图中,并且我可以开始并依赖它作为我主要的初始数据探索阴谋。这是生成图的最终代码,以防其他人发现它们有用(或发现可以改进的东西)。对箱线图进行了很多调整。
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
#change the linewidth which to get a thicker confidence interval line
mpl.rc("lines", linewidth=3)
df = sns.load_dataset("titanic")
df.dropna(inplace=True)
x = 'who'
y = 'age'
fig, (ax1,ax2) = plt.subplots(1,2, sharey=True, figsize=(12,6))
#Left hand plot
sns.violinplot(df[y], groupby=df[x], ax=ax1, inner='stick')
#Right hand plot
sns.violinplot(df[y], groupby=df[x], ax=ax2, positions=0)
sns.pointplot(df[x],df[y], join=False, ci=99, n_boot=1000, ax=ax2, color=[0.3,0.3,0.3], markers=' ')
df.boxplot(y, by=x, sym='_', ax=ax2, showbox=False, showmeans=True, whiskerprops={'linewidth':0},
medianprops={'linewidth':0}, flierprops={'markeredgecolor':'k', 'markeredgewidth':1},
meanprops={'marker':'_', 'color':'w', 'markersize':6, 'markeredgewidth':1.5},
capprops={'linewidth':1, 'color':[0.3,0.3,0.3]}, positions=[0,1,2])
#One could argue that this is not beautiful
labels = [item.get_text() + '\nn=' + str(df.groupby(x).size().loc[item.get_text()]) for item in ax2.get_xticklabels()]
ax2.set_xticklabels(labels)
#Clean up
fig.suptitle('')
ax2.set_title('')
fig.set_facecolor('w')
编辑:添加 'n='