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

时间:2016-03-10 15:37:46

标签: python pandas overlay seaborn

我从一组“观察计数与浓度”中绘制了一个Seaborn libprotoc 2.5.0,它存储在一只大熊猫JointPlot中。我想在现有边际上叠加(在同一组轴上)每个浓度的“预期计数”的边际(即:单变量分布),以便可以很容易地比较差异。

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

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

df_observed

DataFrame

df_expected

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)

x axis--> log2(concentration): 1,1,1,2,2,2,3,3,3 的{​​{1}}分布在df_expected之上的重叠将表明每个浓度都缺少计数。

我目前拥有什么

Jointplot with the observed counts at each concentration Separate jointplot of the expected counts at each concentration. I want the marginal from this plot to be overlaid on top of the marginal from the above jointplot

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

4 个答案:

答案 0 :(得分:5)

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

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

enter image description here

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

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'])),
    )

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

欢迎使用Stack Overflow!

答案 1 :(得分:1)

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

这是用法示例:

enter image description here

示例数据:

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])

函数定义:

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)

用法:

multivariateGrid('x', 'y', 'kind', df=df)

答案 2 :(得分:0)

您可以直接在JointGrid.ax_marg_xJointGrid.ax_marg_y属性上绘制,这些属性是潜在的matplotlib轴。

答案 3 :(得分:0)

现在在带有 hue 参数的 Seaborn 0.11 中:

sns.jointplot(data=penguins, x="bill_length_mm", y="bill_depth_mm", hue="species")

enter image description here