seaborn pairgrid:使用2个色调的kdeplot

时间:2015-10-01 14:02:43

标签: python plot seaborn

这是我努力绘制一个使用下部的kdeplot和2个色调的双网格图:

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中是否有办法根据色调在map_lower的kdeplot中使用更多的色阶?

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

4 个答案:

答案 0 :(得分:6)

您需要创建由PairGrid调用的自己的绘图函数,格式为myplot(x,y,** kws)。 kws包含由PairGrid自动创建的字段'color'或由您在PairGrid的Palette参数中给出的字段。

要控制从Palette中给出的颜色中选择色彩映射的方式,最好手动设置此参数,并使用字典将传递给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()

答案 1 :(得分:5)

我认为在PairGrid中使用hue_kwds非常容易。 我在Plotting on data-aware grids找到了一个很好的解释,因为PairGrid中的doc对我来说不够清楚。

  

你还可以让情节的其他方面在不同的层次上有所不同   色调变量,这可以帮助制作更多的情节   用黑白打印时可理解。要做到这一点,通过一个   字典到hue_kws,其中键是绘图函数的名称   关键字参数和值是关键字值列表,每个值对应一个   色调变量的等级。

基本上,hue_kws是列表的字典。关键字将通过列表中的值传递给单个绘图函数,每个级别对应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

答案 2 :(得分:1)

如Martin的例子所示,需要创建一个包装函数来指示sns.kdeplot使用哪些颜色贴图。这是一个类似的例子,应该更容易理解:

# 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。)。但是,我们正在使用具有不同RBG元组的上述托盘。

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

答案 3 :(得分:0)

尝试在huekdeplot()上使用distplot()时,我遇到了这个问题。这工作

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