使用seaborn绘制配对数据

问题描述 投票:0回答:1

我正在尝试使用seaborn的面向对象界面来绘制配对数据图,其中每对数据都通过线段连接。我希望最终图中的单个子图如下所示:

expected output

我能得到的最接近的是:

import numpy as np
import pandas as pd
import seaborn.objects as so
np.random.seed(0)
df = pd.DataFrame({
                'Treated':['N']*10+['Y']*10,
                  'Treatment':['A']*20,
                  'value':np.random.random(20),
                    'Individual': [str(i) for i in list(range(10))+list(range(10))],
                'Genotype':(['WT']*5+['M1']*5)*2
                                                       
                                                       
})


p=(
    so.Plot(df,
            x= 'Treatment',y='value',
            # color='Individual',
            color='Genotype',
            fill='Treated',
           )
    
    .add(so.Dot(),so.Dodge(by=['fill']),so.Jitter(width=.00,seed=0),group = "Individual",
         legend=True)
    .add(so.Line(),so.Dodge(by=['fill']),so.Jitter(width=.00,seed=0),legend=None,group = "Individual")
    
    .scale(
        fill =so.Nominal(['N','Y'],order = ["N","Y"]),
    )
)
p.show()
            

Seaborn 输出: Seaborn output

添加 group="Individual" 会在情节中引入额外的、不需要的闪避。如果没有它,线不会连接点对,而是将所有点相互连接。

我正在寻找一种方法将不同的变量传递到线条中,覆盖组的自动躲避效果或完全不同的方式。

python seaborn-0.12.x
1个回答
0
投票

可能有一个更优雅的答案,但可以手动添加单独的行,如下所示。

import numpy as np
import seaborn as sns
import pandas as pd
import seaborn.objects as so
np.random.seed(0)
df = pd.DataFrame({
                'Treated':['N']*10+['Y']*10,
                  'Treatment':['A']*20,
                  'value':np.random.random(20),
                    'Individual': [str(i) for i in list(range(10))+list(range(10))],
                'Genotype':(['WT']*5+['M1']*5)*2
                                                       
                                                       
})


p=(
    so.Plot(df,
            x= 'Treatment',y='value',
            # color='Individual',
            color='Genotype',
            fill='Treated',
           )
    
    .add(so.Dot(),so.Dodge(by=['fill']),so.Jitter(width=.05,seed=0),
         legend=True)
    # .add(so.Line(),so.Dodge(by=['fill']),so.Jitter(width=.00,seed=0),legend=None,group = "Individual")

    .scale(
        fill =so.Nominal(['N','Y'],order = ["N","Y"]),
    )
    
)

####### add lines for each individual #######
for i in df['Individual'].unique():
    p = p.add(so.Line(pointsize=0),so.Dodge(by=['fill']),legend=None,data=df[df['Individual']==i])
####### add lines for each individual #######
p.show()

所需的seaborn输出

© www.soinside.com 2019 - 2024. All rights reserved.