叠加两个 seaborn 因子图

Superimpose two seaborn factorplots

我在使用 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

绘制两个 factorplot 就好像它是 sns.pointplot 两次类似于 一样。由于数据的实验设置,我需要 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')

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

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

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

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

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()