Python seaborn中的一半(未分割!)小提琴情节

Python seaborn中的一半(未分割!)小提琴情节,python,python-3.x,pandas,seaborn,Python,Python 3.x,Pandas,Seaborn,目前,seaborn通过设置split=True,根据hue变量提供服务。我想做一个“半”小提琴情节,即每把小提琴的一半都被省略的情节。这样的图为每个连续变量描绘了类似于pdf的东西,仅绘制在每个分类变量的每条垂直线的一侧 我已经设法欺骗了seaborn,在绘制的值范围之外绘制了一个额外的数据点和一个额外的虚拟色调,但我想知道这是否可以在不改变数据集的情况下完成,例如在sns.violinplot()参数内 例如,此图: 由以下代码段创建: # imports import pandas as

目前,seaborn通过设置
split=True
,根据
hue
变量提供服务。我想做一个“半”小提琴情节,即每把小提琴的一半都被省略的情节。这样的图为每个连续变量描绘了类似于pdf的东西,仅绘制在每个分类变量的每条垂直线的一侧

我已经设法欺骗了
seaborn
,在绘制的值范围之外绘制了一个额外的数据点和一个额外的虚拟色调,但我想知道这是否可以在不改变数据集的情况下完成,例如在
sns.violinplot()参数内

例如,此图:

由以下代码段创建:

# imports
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# load dataset from seaborn
datalist = sns.get_dataset_names()
dataset_name = 'iris'
if dataset_name in datalist:
    df = sns.load_dataset(dataset_name)
else:
    print("Dataset with name: " + dataset_name + " was not found in the available datasets online by seaborn.")

# prepare data
df2 = df.append([-999,-999,-999,-999,'setosa'])
df2['huecol'] = 0.0
df2['huecol'].iloc[-1]= -999

# plot
fig = plt.figure(figsize=(6,6))
sns.violinplot(x='species',y="sepal_width",
            split=True, hue ='huecol', inner = 'quartile',
            palette="pastel", data=df2, legend=False)
plt.title('iris')

# remove hue legend
leg = plt.gca().legend()
leg.remove()
plt.ylim([1,5.0])
plt.show()

答案很简单,不,如果seaborn不诱使它认为存在一种
色调
是不可能的


显示了如何在matplotlib中执行此操作,原则上同样可以应用于seaborn violinplots,即剪切一半小提琴路径。

我正在寻找类似的解决方案,但没有发现任何令人满意的结果。最后我多次调用violinplot,因为violinplot本质上是一个片面的内核密度图

例子 下面的
分类图的函数定义

使用
horizontal=True
,输出如下所示:

代码
导入seaborn作为sns
从matplotlib导入pyplot作为plt
def分类图(
df,
变量
类别
类别\顺序=无,
水平=假,
rug=正确,
figsize=无,
):
“”“绘制分类KDE图
参数
----------
df:pd.DataFrame
要绘制的数据
变量:str
“df”中要绘图的列(连续变量)
类别:str
“df”中用于分组的列(分类变量)
水平:布尔
如果为True,则水平绘制密度图。否则,绘制密度图
垂直地
地毯:布尔
如果为True,则还添加一个sns.rugplot。
figsize:元组或无
如果没有,则使用默认的figsize(7,1*len(类别))
如果是tuple,则使用给定给plt.subplot的figsize.作为参数。
"""
如果类别订单为“无”:
类别=列表(df[category].unique())
其他:
类别=类别\顺序[:]
figsize=(7,1.0*len(类别))
图,轴=plt子批次(
nrows=长度(类别),如果水平,则为1,
ncols=1,如果水平else len(类别),
figsize=figsize[:-1]如果不是水平的,则为figsize,
sharex=水平,
sharey=非水平,
)
对于枚举(zip(类别、轴))中的i(cat、ax):
sns.kdeplot(
数据=df[df[类别]==cat],
x=变量,如果为水平,则为无,
y=无,如果为水平变量,
#kde kwargs
bw_调整=0.5,
clip_on=False,
填充=真,
α=1,
线宽=1.5,
ax=ax,
color=“浅灰色”,
)
如果水平,则保持变量_轴=(i==len(图轴)-1),否则(i==0)
如果地毯:
小地毯(
数据=df[df[类别]==cat],
x=变量,如果为水平,则为无,
y=无,如果为水平变量,
ax=ax,
color=“黑色”,
高度=0.025,如果保持可变轴,否则为0.04,
)
_格式化U轴(
斧头,
猫,
水平的,
保持变量轴=保持变量轴,
)
plt.紧_布局()
plt.show()
定义格式轴(ax、类别、水平=假、保持变量轴=真):
#删除轴线
ax.脊椎[“顶部”]。设置为可见(假)
ax.脊椎[“右”]。设置为可见(假)
如果水平:
ax.set_ylabel(无)
lim=ax.get_ylim()
ax.set_yticks([(lim[0]+lim[1])/2])
ax.set_yticklabels([类别])
如果不保持_变量_轴:
ax.get_xaxis().set_visible(False)
ax.脊椎[“底部”]。设置为可见(假)
其他:
ax.集合标签(无)
lim=ax.get_xlim()
ax.set_xticks([(lim[0]+lim[1])/2])
ax.setxticklabel([类别])
如果不保持_变量_轴:
ax.get_yaxis().set_visible(False)
ax.脊椎[“左”]。设置为可见(假)
如果名称=“\uuuuu main\uuuuuuuu”:
df=sns.load_数据集(“提示”)
分类图(
df,
variable=“tip”,
category=“day”,
分类顺序=[“星期四”、“星期五”、“星期六”、“星期日”],
水平=真,
)

使用matplotlib而不是seaborn,但这可能会有所帮助:临时修改数据以生成绘图有什么问题?感谢您的链接,但能否提供与
seaborn
相同的代码?谢谢更新:其实它不应该是一样的,只是小提琴的一半。链接中的情节是双面小提琴,这不是TS要求的。@SergeyZakharov问题中的代码显示了如何使用seaborn。我想我不必重复了。链接的matplotlib代码分别生成小提琴的两面;我想很明显,如果你只想要半把小提琴,你只需要省略答案的两部分中的一部分。现在我知道怎么做了。谢谢
categorical_kde_plot(
    df,
    variable="tip",
    category="day",
    category_order=["Thur", "Fri", "Sat", "Sun"],
    horizontal=False,
)