Cómo superponer un gráfico conjunto de Seaborn con un “marginal” (histogtwig de distribución) de un conjunto de datos diferente

He trazado un Seaborn JointPlot partir de un conjunto de “conteos observados frente a la concentración” que se almacenan en un DataFrame pandas. Me gustaría superponer (en el mismo conjunto de ejes) un marginal (es decir, una distribución univariada) de los “conteos esperados” para cada concentración sobre el marginal existente, de modo que la diferencia se pueda comparar fácilmente.

Este gráfico es muy similar a lo que quiero, aunque tendrá diferentes ejes y solo dos conjuntos de datos:

Aquí hay un ejemplo de cómo mis datos están distribuidos y relacionados:

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) 

df_expected

 x axis--> log2(concentration): 1,1,1,2,2,2,3,3,3 

por lo tanto, una superposición de la distribución de df_expected sobre la de df_observed indicaría dónde faltaban recuentos en cada concentración.

Lo que tengo actualmente

Diagtwig conjunto con los recuentos observados en cada concentración Gráfico conjunto separado de los recuentos esperados en cada concentración. Quiero que el marginal de esta plot se superponga sobre el marginal de la gráfica de puntos anterior

PD: Soy nuevo en Stack Overflow, por lo que cualquier sugerencia sobre cómo hacer mejor las preguntas será recibida con gratitud. Además, he buscado extensivamente una respuesta a mi pregunta, pero sin éxito. Además, una solución Plotly sería igualmente útil. Gracias

Cuando trato de modificar un JointPlot más de lo que estaba destinado, me dirijo a un JointGrid en su lugar. Te permite cambiar los parámetros de las plots en los marginales.

A continuación se muestra un ejemplo de un JointGrid de trabajo donde agrego otro histogtwig para cada marginal. Estos histogtwigs representan el valor esperado que desea agregar. Tenga en cuenta que generé datos aleatorios por lo que probablemente no se parece a los suyos.

introduzca la descripción de la imagen aquí

Eche un vistazo al código, donde modifiqué el rango de cada segundo histogtwig para que coincida con el rango de los datos observados.

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

La parte en la que llamo plt.ion plt.show plt.pause es lo que uso para mostrar la figura. De lo contrario, no aparece ninguna figura en mi computadora. Puede que no necesites esta parte.

Bienvenido a Stack Overflow!

Puede trazar directamente en los JointGrid.ax_marg_x y JointGrid.ax_marg_y , que son los ejes subyacentes de matplotlib.

Escribió una función para trazarla, muy libremente basada en la idea de @ blue_chip. Es posible que aún tengas que modificarlo un poco para tus necesidades específicas.

Aquí hay un ejemplo de uso: introduzca la descripción de la imagen aquí datos de ejemplo:

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

definición de la función:

 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) 

uso:

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