使用指标变量而不是单个列创建刻面matplotlib / seaborn图

时间:2017-02-08 22:40:11

标签: python matplotlib plot seaborn

Seaborn非常适合根据编码每个方面类别的分类变量创建分面图。但是,这假设您的类别是互斥的。是否可以根据一组指标变量创建Seaborn <a>(或类似)?

作为一个具体的例子,考虑比较感染了一种或多种病毒的病人,并用病毒绘制感兴趣的属性。患者可能携带多种病毒,因此无法创建h1#text列以创建网格。但是,您可以为每个患者创建一组标记病毒的指示变量(每个病毒一个)。似乎没有办法将一组指标变量传递给任何Seaborn函数来执行此操作。

enter image description here

我无法想象我是第一个遇到这种情况的人,所以我希望有关于如何做到这一点的建议,而不是在Matploltlib中手工编写。

1 个答案:

答案 0 :(得分:3)

我不知道如何使用FacetGrid,可能是因为这不是数据的表面,因为数据记录可能会在图中出现几次或只出现一次。带有一组位域的标准技巧之一是将它们读为二进制,因此您可以看到每个位的组合。这是毫不含糊的,但却变得混乱:

import pandas as pd
import seaborn as sns
from numpy.random import random, randint
from numpy import concatenate
import matplotlib.pyplot as plt

# Dummy data
vdata = pd.DataFrame(concatenate((randint(2, size=(32,4)), random(size=(32,2))), axis=1))
vdata.columns=['Species','v1','v2','v3','x','y']
binary_v = vdata.v1 + vdata.v2*2 + vdata.v3*4
# Making a binary number out of the "virusX?" fields 
pd.concat((vdata, binary_v), axis=1)
vdata = pd.concat((vdata, binary_v), axis=1)
vdata.columns=['Species','v1','v2','v3','x','y','binary_v']

# Plotting group membership by row
#g = sns.FacetGrid(vdata, col="Species", row='binary_v')
#g.map(plt.scatter, "x", "y")
#g.add_legend()
#plt.savefig('multiple_facet_binary_row') # Unreadably big. 

h = sns.FacetGrid(vdata, col="Species", hue="binary_v")
h.map(plt.scatter, "x","y")
h.add_legend()
plt.savefig('multiple_facet_binary_hue')

enter image description here

如果您有太多指标来处理组合爆炸,请明确使新子集有效:

# Nope, need to pull out subsets:
bdata = vdata[vdata.v1 + vdata.v2 + vdata.v3 ==0.]
assert(len(bdata) > 0) # ... catch... 
bdata['Virus'] = pd.Series(['none']*len(bdata), index=bdata.index)

for i in ['v1','v2','v3']:
    on = vdata[vdata[i]==1.]
    on['Virus'] = pd.Series([i]*len(on), index=on.index)
    bdata = bdata.append(on)

j = sns.FacetGrid(bdata, col='Species', row='Virus')
j.map(plt.scatter, 'x', 'y')
j.add_legend()
j.savefig('multiple_facet_refish')

enter image description here