【问题标题】:Superimpose two seaborn factorplots叠加两个 seaborn 因子图
【发布时间】:2018-04-28 17:34:02
【问题描述】:

我在使用 seaborn 库对两个 factorplots 进行叠加(叠加)时遇到了困难。

一般的问题是,我想用灰色细线绘制所有(背景数据),然后在顶部用彩色、粗线绘制我们想要突出显示的数据。一方面,我没有成功地将两个数据集与FacetGrid 组合在一个绘图中,其次我在使用zorder 时遇到了问题。

我用exercise 数据集做了一个虚拟示例:

sns.set_style('whitegrid')
exercise = sns.load_dataset("exercise")
background = exercise.assign(idkind = lambda df: df['id'].astype(str)+df.kind.astype(str))
foreground = exercise.groupby(['kind','time']).mean().reset_index().rename(columns={'id':'idkind'})

到目前为止我尝试过:

  1. factorplot + factorplot

绘制两个factorplots,就好像它是sns.pointplot 两次模拟this example。由于数据的实验设置,我需要sns.factorplot。这不起作用,因为只生成了两个独立的图。我基本上希望下图在上图之上。

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
sns.factorplot(x="time", y="pulse", hue="kind", data=foreground)

  1. factorplot + gmap.(factorplot)

因此,我尝试使用sns.factorplot,我认为它会在顶部使用具有完全相同设计和类别的新数据集生成FacetGridg.map 第二个sns.factorplot。结果是,它没有使用相同的子图,而是创建了许多具有重复图的行。

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
g.map(sns.factorplot, x="time", y="pulse",hue='idkind', col='kind', data=foreground)

  1. factorplot+ g.map(pointplot)

g.map一个点图,将整个数据集放在所有子图中,不尊重FacetGrid的设计。

g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', legend=False,color='lightgrey',data=background)
g.map(sns.pointplot,x="time", y="pulse", hue='idkind', col='kind', data=foreground,zorder='1000')

【问题讨论】:

    标签: python matplotlib plot seaborn facet-grid


    【解决方案1】:

    值得一提的是,每次调用factorplot 都会创建自己的图形。所以一般来说,如果目标是有一个单一的数字,你不能多次调用 factorplot。这解释了为什么 1. 和 2. 根本行不通。

    对于 3.,这也是我的第一次尝试(除了 zorder 应该是一个数字,而不是一个字符串)。
    然而,似乎 zorder 被忽略了,或者至少没有正确地传递给底层的 matplotlib 函数。

    一个选项是手动设置 zorder。以下循环遍历背景图的所有艺术家并将他们的 zorder 设置为 1。它还将这些艺术家存储在一个列表中。 在创建前景图之后,我们可以再次遍历所有艺术家,并将 zorder 设置为更高的值,以便那些不在先前存储的列表中的艺术家。

    我在这里完全省略了foreground,因为这似乎只是计算平均值,这将通过点图自动完成。

    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set_style('whitegrid')
    exercise = sns.load_dataset("exercise")
    background = exercise.assign(idkind = lambda df: df['id'] \
                                .astype(str)+df.kind.astype(str))
    
    g=sns.factorplot(x="time", y="pulse", hue='idkind', col='kind', 
                     legend=False,color='lightgrey',data=background)
    
    backgroundartists = []
    for ax in g.axes.flat:
        for l in ax.lines + ax.collections:
            l.set_zorder(1)
            backgroundartists.append(l)
    
    g.map(sns.pointplot, "time", "pulse")
    
    for ax in g.axes.flat:
        for l in ax.lines + ax.collections:
            if l not in backgroundartists:
                l.set_zorder(5)
    
    plt.show()
    

    【讨论】:

    • 嗨。非常感谢您的回答和澄清。我认为您的解决方案仍然存在所有三个图都包含所有三个种类的前景数据的问题。这是我的另一个问题,它不会尊重FacetGrid。最后,我认为我只需要为每个 kind 制作单独的情节。无论如何,您的回答有助于强调我如何区分“背景和前景”的元素
    • 抱歉,我没有意识到这是问题所在。所以不要将foreground 提供给映射。它是应该映射的原始数据集。我更新了答案。
    • zorder 是做什么的?
    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 2015-09-18
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多