Seaborn PairGrid: 使用带有两种颜色的 kdeplot

13

这是我努力绘制的一张包含2个色调的kdeplot的pairgrid图:

enter image description here

我的脚本如下:

import seaborn as sns
g = sns.PairGrid(df2,hue='models')  
g.map_upper(plt.scatter)
g.map_lower(sns.kdeplot)
g.map_diag(sns.distplot)

在 seaborn 0.6.0 中,有没有一种方法可以根据 hue 使用更多的颜色比例尺来在 map_lower 的 kdeplot 中使用?

在这种情况下,hue 只有2个值。也许我错过了一些显而易见的东西。


你需要为 kdeplot 编写一个小的包装函数,使其能够理解双变量图中的“颜色”参数,并使用它来选择适当的颜色映射,例如使用 sns.dark_palette。等我有时间时,我会做一个例子,但这可能会有所帮助。 - mwaskom
4个回答

10
  • sns.kdeplot:将shade_lowest替换为thresh,将shade替换为fill。但是,现在不再需要指定这些参数。
  • sns.distplot已被sns.histplot替换。
  • seaborn 0.12.0中测试通过。
import seaborn as sns
from sklearn.datasets import make_blobs
import numpy as np

# generate data
n = 1000
X, y = make_blobs(n_samples=n, centers=3, n_features=3, random_state=0)

df2 = pd.DataFrame(data=np.hstack([X, y[np.newaxis].T]), columns=['X', 'Y', 'Z','model'])

# kdeplot and histplot treat numbers and strings differently when using hue.
# since model is a category, convert the column to a string type
df2['model'] = df2['model'].astype(str)

g = sns.PairGrid(df2, hue='model')

g.map_upper(plt.scatter)
g.map_lower(sns.kdeplot)
g.map_diag(sns.histplot, kde=True, stat='density', bins=20)

_ = g.add_legend()

enter image description here


原始回答

我认为在PairGrid中使用要容易得多。

我在这里找到了一个很好的解释 Plotting on data-aware grids,因为PairGrid中的文档对我来说不够清晰。

您还可以让绘图的其他方面随hue变量的级别而变化,这有助于制作更易于在黑白打印时理解的图形。为此,请将字典传递给hue_kws,其中键是绘图函数关键字参数的名称,值是关键字值的列表,每个值都对应hue变量的一个级别。

本质上,是一个列表字典。关键字被传递到单个绘图函数中,其值来自其列表,每个值对应于您的变量的每个级别。请参见下面的代码示例。

我在分析中使用数字列作为hue,但它也应该在这里起作用。如果不行,您可以轻松地将“models”的每个唯一值映射到整数。

Martin Perez的好回答中借鉴,我会做如下处理:
编辑:完整的代码示例
编辑2:我发现kdeplot与数字标签不兼容。相应地更改了代码。
# generate data: sorry, I'm lazy and sklearn make it easy.
n = 1000
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=n, centers=3, n_features=3,random_state=0)

df2 = pd.DataFrame(data=np.hstack([X,y[np.newaxis].T]),columns=['X','Y','Z','model'])
# distplot has a problem witht the color being a number!!!
df2['model'] = df2['model'].map('model_{}'.format)

list_of_cmaps=['Blues','Greens','Reds','Purples']
g = sns.PairGrid(df2,hue='model',
      # this is only if you use numerical hue col
#     vars=[i for i in df2.columns if 'm' not in i], 
    # the first hue value vill get cmap='Blues'
    # the first hue value vill get cmap='Greens'
    # and so on
    hue_kws={"cmap":list_of_cmaps},
    )
g.map_upper(plt.scatter)
g.map_lower(sns.kdeplot,shade=True, shade_lowest=False)
g.map_diag(sns.distplot)
# g.map_diag(plt.hist)
g.add_legend()

enter image description here

对于编程相关内容,您可以通过排序list_of_cmaps来为您的分类变量的特定级别分配特定阴影。

升级版是根据您需要的级别数量动态创建list_of_cmaps


7
您需要创建自己的绘图函数,由PairGrid调用,形式为myplot(x,y,**kws)。 kws包含“color”字段,该字段由PairGrid自动创建或由您在PairGrid的调色板参数中给出。
为了控制如何从调色板中选择颜色,您最好手动设置此参数,使用链接变量传递给hue的变量值与您选择的颜色的字典。
以下是仅包含4种颜色(红色,绿色,蓝色和品红色)的示例。导致颜色映射:红色、绿色、蓝色和紫色。
根据颜色推断cmap
def infer_cmap(color):  
    if color == (0., 0., 1.):
        return 'Blues'
    elif color == (0., 0.5, 0.):
        return 'Greens'
    elif color == (1., 0., 0.):
        return 'Reds'
    elif color == (0.75, 0., 0.75):
        return 'Purples'

为KDE图添加色调

def kde_hue(x, y, **kws):
    ax = plt.gca()
    cmap = infer_cmap(kws['color'])
    sns.kdeplot(data=x, data2=y, ax=ax, shade=True, shade_lowest=False, cmap=cmap, **kws)
    return ax

创建PairGrid

colors = ['b', 'g', 'r', 'm']
var = 'models'

color_dict = {}
for idx, v in enumerate(np.unique(df2[var])):
    color_dict[v] = colors[idx]
g = sns.PairGrid(df2, hue=var, palette=color_dict)
g = g.map_diag(sns.kdeplot)
g = g.map_upper(plt.scatter)
g = g.map_lower(kde_hue)
g = g.add_legend()
plt.show()
plt.close()

2
正如Martin的示例所示,需要创建一个包装函数来指示使用哪个颜色映射。以下是一个类似的示例,应该更容易理解:
# We will use seaborn 'Set1' color pallet

>>> print(sns.color_palette('Set1'))

[(0.89411765336990356, 0.10196078568696976, 0.10980392247438431),
 (0.21602460800432691, 0.49487120380588606, 0.71987698697576341),
 (0.30426760128900115, 0.68329106055054012, 0.29293349969620797),
 (0.60083047361934883, 0.30814303335021526, 0.63169552298153153),
 (1.0, 0.50591311045721465, 0.0031372549487095253),
 (0.99315647868549117, 0.9870049982678657, 0.19915417450315812)]

颜色映射根据调色板接收颜色。默认调色板为绿色 - (0.,0.,1.) 和蓝色 - (0.,0.5,0.)。但是,我们正在使用具有不同 RGB 元组的上述调色板。

def infer_cmap(color):
    hues = sns.color_palette('Set1')
    if color == hues[0]:
        return 'Reds'
    elif color == hues[1]:
        return 'Blues'

def kde_color_plot(x, y, **kwargs):
    cmap = infer_cmap(kwargs['color'])
    ax = sns.kdeplot(x, y, shade=True, shade_lowest=False, cmap=cmap, **kwargs)
    return ax

g = sns.PairGrid(df, hue='left', vars=['satisfaction_level', 'last_evaluation'], palette='Set1')
g = g.map_upper(plt.scatter, s=1, alpha=0.5)
g = g.map_lower(kde_color_plot)
g = g.map_diag(sns.kdeplot, shade=True);

enter image description here


2

当我尝试在kdeplot()distplot()上使用hue参数时,发现该参数不被支持。这个可以解决。

g = sns.FacetGrid(df_rtn, hue="group")
g = g.map(sns.kdeplot, "variable")
# or
g = g.map(sns.distplot, "variable")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接