【问题标题】:How to use seaborn pointplot and violinplot in the same figure? (change xticks and marker of pointplot)如何在同一图中使用 seaborn 点图和小提琴图? (更改点图的 xticks 和标记)
【发布时间】:2015-02-04 00:32:03
【问题描述】:

我正在尝试创建显示均值置信区间的小提琴图。我认为一个简单的方法是在小提琴图的顶部绘制一个点图,但这不起作用,因为它们似乎使用不同的 xaxis 索引,如本例所示:

import matplotlib.pyplot as plt
import seaborn as sns   

titanic = sns.load_dataset("titanic")
titanic.dropna(inplace=True)
fig, (ax1,ax2,ax3) = plt.subplots(1,3, sharey=True, figsize=(12,4))
#ax1
sns.pointplot("who", "age", data=titanic, join=False,n_boot=10, ax=ax1)
#ax2
sns.violinplot(titanic.age, groupby=titanic.who, ax=ax2)
#ax3
sns.pointplot("who", "age", data=titanic, join=False, n_boot=10, ax=ax3)
sns.violinplot(titanic.age, groupby=titanic.who, ax=ax3)
ax3.set_xlim([-0.5,4])

print(ax1.get_xticks(), ax2.get_xticks())

给出:[0 1 2] [1 2 3]

为什么这些图没有为“谁”变量分配相同的 xtick 数字,我有什么办法可以改变它?

我还想知道是否可以更改点图的标记,因为正如您在图中看到的那样,点太大以至于它覆盖了整个置信区间。如果可能的话,我只想要一条水平线。

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    我在这里发布我的最终解决方案。我一开始想做这种图的原因是在同一个图中显示有关分布形状、均值变化和异常值的信息。通过 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='

    【讨论】:

    • 我喜欢你的问题 - 小提琴图很有用,但可以通过置信水平和修改显示异常值的方式来改进。自从这篇文章以来,您是否改进了您的代码?如果你有的话,我很想看看。
    • 感谢和抱歉迟到的回复!除了添加两条不同的异常值线之外,我并没有真正采取更进一步的措施,一条用于分位数截止值以及我在上图中使用的四分位数范围。我也开始倾向于直接绘制数据点而不是小提琴,至少在我的样本量不大的情况下。
    • 这是个好主意,仅当所有样本集的数据都稀疏时才选择小提琴。祝你好运!
    【解决方案2】:

    violinplot 采用 positions 参数,您可以使用该参数将小提琴放在其他位置(它们目前只是继承默认的 matplotlib 箱线图位置)。

    pointplot 采用 markers 参数,您可以使用该参数来更改点估计的呈现方式。

    【讨论】:

    • 非常感谢。我发誓我尝试了标记论点,但即使我按照与现在的工作方式完全相同的方式进行操作,也无法使其工作......哦,好吧。我最初不想同时移动小提琴和箱线图,但因为我认为它会更复杂,但毕竟它很漂亮。我也发布了我的最终数据。如果 seaborn 中的默认小提琴图可以显示异常值和胡须帽(可能带有“外部”参数),那就太酷了,但我知道你说代码需要重构,所以我会坚持我的 hacky 情节-一段时间的现场解决方案。
    猜你喜欢
    • 2021-01-29
    • 2019-07-08
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2017-12-01
    • 2023-03-31
    • 2019-03-08
    • 2022-10-14
    相关资源
    最近更新 更多