我有一些数据,这些数据与离散的Likert尺度样测量(Xn)和连续量(Y)之间有关系。在探讨这种关系时,我既对每个类别内的关系(Y与Xn)感兴趣,又对各个答案在类别内和跨类别的分布(X1[1]
与X2[1]
与X3[1]
既感兴趣等)。
此代码大致显示了我的意思(甜点问题是Xn,得分是Y):
import numpy as np
import pandas as pd
import seaborn as sns
sns.set()
from matplotlib import pyplot as plt
questions = ['Cupcakes', 'Biscuits', 'Sweets']
df = pd.DataFrame({
question: np.random.randint(1, 6, 1000)
for question in questions
})
df['Score'] = np.random.normal(df[questions].sum(axis=1))
df = df.melt(
id_vars=['Score'], value_vars=questions,
var_name='Question', value_name='Answer'
)
此刻,我可以使用Seaborn通过以下方式可视化每个关系和每个答案的分布:
sns.lmplot(
data=df, x='Answer', y='Score',
col='Question', hue='Question',
x_jitter=0.1, scatter_kws={'alpha': 0.1}
);
抖动和alpha可以使例如的形状更清晰。所有杯形蛋糕的答案,或者让我快速比较类别之间的所有“ 5”个答案。
但是抖动的散点图实际上只是我认为理想的替代品:小提琴图。
如果我尝试在lmplot()
上使用小提琴图,将会发生以下情况:
lmp = sns.lmplot(
data=df, x='Answer', y='Score',
col='Question', hue='Question',
scatter=False
);
ss = lmp.map_dataframe(sns.violinplot, x='Answer', y='Score')
(忽略透明度的问题,这很容易解决。)请注意,与回归线相比,小提琴图向左偏移了一个单位。这是因为小提琴图仅用于抽象的分类数据,而Seaborn将分类的坐标从零开始。回归图从1开始,因为那是数据的下限。轴标签是小提琴图的类别标签,而不是数字标签(因此标签1实际上是数字0)。
如何定位小提琴图,使其分类定位与这些类别的自然数值表示对齐?
Seaborn的问题跟踪器(#859, Allow specifying of x position for categorical plots)中存在此问题,但开发人员已决定不包括此功能。我曾尝试直接用Matplotlib代码制作小提琴图,但是要获得与Seaborn的小提琴图相同的质量和细节(例如中心线可视化效果)非常困难。