如何使用来自不同数据集的"边缘"(分布直方图)覆盖Seaborn关节图

Non*_*ant 5 python overlay pandas seaborn

JointPlot从一组存储在大熊猫中的"观察计数与浓度"中绘制了一个Seaborn DataFrame.我想在现有边际之上覆盖(在同一组轴上)每个浓度的"预期计数"的边际(即:单变量分布),以便可以容易地比较差异.

这个图与我想要的非常相似,虽然它有不同的轴,只有两个数据集:

以下是我的数据如何布局和相关的示例:

df_observed

x axis--> log2(concentration): 1,1,1,2,3,3,3 (zero-counts have been omitted)

y axis--> log2(count): 4.5, 5.7, 5.0, 9.3, 16.0, 16.5, 15.4 (zero-counts have been omitted)
Run Code Online (Sandbox Code Playgroud)

df_expected

x axis--> log2(concentration): 1,1,1,2,2,2,3,3,3
Run Code Online (Sandbox Code Playgroud)

因此,覆盖在其df_expected上方的分布df_observed将表明每个浓度中缺少计数的位置.

我现在有什么

在每个浓度下观察到的计数的联合图分别在每个浓度 下的预期计数的联合图.我希望这个图的边缘覆盖在上面的联合图的边缘之上

PS:我是Stack Overflow的新手,所以任何有关如何更好地提问的建议都将得到感谢.此外,我已经广泛搜索了我的问题的答案,但无济于事.此外,Plotly解决方案同样有用.谢谢

blu*_*hip 6

每当我尝试修改一个JointPlot而不是它的目的时,我转而使用JointGrid.它允许您更改边距中的图的参数.

下面是一个工作JointGrid的示例,我在其中为每个边缘添加另一个直方图.这些直方图表示您要添加的预期值.请记住,我生成了随机数据,因此它可能看起来不像你的.

在此输入图像描述

看看代码,我改变了每个第二直方图的范围,以匹配观察数据的范围.

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.DataFrame(np.random.randn(100,4), columns = ['x', 'y', 'z', 'w'])

plt.ion()
plt.show()
plt.pause(0.001)

p = sns.JointGrid(
    x = df['x'],
    y = df['y']
    )

p = p.plot_joint(
    plt.scatter
    )

p.ax_marg_x.hist(
    df['x'],
    alpha = 0.5
    )

p.ax_marg_y.hist(
    df['y'],
    orientation = 'horizontal',
    alpha = 0.5
    )

p.ax_marg_x.hist(
    df['z'],
    alpha = 0.5,
    range = (np.min(df['x']), np.max(df['x']))
    )

p.ax_marg_y.hist(
    df['w'],
    orientation = 'horizontal',
    alpha = 0.5,
    range = (np.min(df['y']), np.max(df['y'])),
    )
Run Code Online (Sandbox Code Playgroud)

我调用的部分plt.ion plt.show plt.pause是我用来显示图形的部分.否则,我的计算机上不会出现图形.您可能不需要这部分.

欢迎来到Stack Overflow!


ntg*_*ntg 5

根据@blue_chip的想法,非常随意地编写了一个函数来绘制它。您可能仍需要针对您的特定需求进行一些调整。

这是一个示例用法:

在此处输入图片说明

示例数据:

import seaborn as sns, numpy as np, matplotlib.pyplot as plt, pandas as 

pd
n=1000
m1=-3
m2=3

df1 = pd.DataFrame((np.random.randn(n)+m1).reshape(-1,2), columns=['x','y'])
df2 = pd.DataFrame((np.random.randn(n)+m2).reshape(-1,2), columns=['x','y'])
df3 = pd.DataFrame(df1.values+df2.values, columns=['x','y'])
df1['kind'] = 'dist1'
df2['kind'] = 'dist2'
df3['kind'] = 'dist1+dist2'
df=pd.concat([df1,df2,df3])
Run Code Online (Sandbox Code Playgroud)

功能定义:

def multivariateGrid(col_x, col_y, col_k, df, k_is_color=False, scatter_alpha=.5):
    def colored_scatter(x, y, c=None):
        def scatter(*args, **kwargs):
            args = (x, y)
            if c is not None:
                kwargs['c'] = c
            kwargs['alpha'] = scatter_alpha
            plt.scatter(*args, **kwargs)

        return scatter

    g = sns.JointGrid(
        x=col_x,
        y=col_y,
        data=df
    )
    color = None
    legends=[]
    for name, df_group in df.groupby(col_k):
        legends.append(name)
        if k_is_color:
            color=name
        g.plot_joint(
            colored_scatter(df_group[col_x],df_group[col_y],color),
        )
        sns.distplot(
            df_group[col_x].values,
            ax=g.ax_marg_x,
            color=color,
        )
        sns.distplot(
            df_group[col_y].values,
            ax=g.ax_marg_y,
            color=color,            
            vertical=True
        )
    # Do also global Hist:
    sns.distplot(
        df[col_x].values,
        ax=g.ax_marg_x,
        color='grey'
    )
    sns.distplot(
        df[col_y].values.ravel(),
        ax=g.ax_marg_y,
        color='grey',
        vertical=True
    )
    plt.legend(legends)
Run Code Online (Sandbox Code Playgroud)

用法:

multivariateGrid('x', 'y', 'kind', df=df)
Run Code Online (Sandbox Code Playgroud)