Parcela de distribución normal en 3D.

Estoy tratando de trazar la distribución de dos variables distribuidas normales.

El siguiente código traza una variable distribuida normal. ¿Cuál sería el código para trazar dos variables distribuidas normales?

import matplotlib.pyplot as plt import numpy as np import matplotlib.mlab as mlab import math mu = 0 variance = 1 sigma = math.sqrt(variance) x = np.linspace(-3, 3, 100) plt.plot(x,mlab.normpdf(x, mu, sigma)) plt.show() 

Parece que lo que estás buscando es una Distribución Normal Multivariada . Esto se implementa en scipy como scipy.stats.multivariate_normal . Es importante recordar que está pasando una matriz de covarianza a la función. Así que para mantener las cosas simples, mantenga los elementos fuera de la diagonal como cero:

 [X variance , 0 ] [ 0 ,Y Variance] 

Aquí hay un ejemplo que usa esta función y genera una gráfica 3D de la distribución resultante. Agrego el mapa de colores para facilitar la visualización de las curvas, pero siéntase libre de eliminarlo.

 import numpy as np import matplotlib.pyplot as plt from scipy.stats import multivariate_normal from mpl_toolkits.mplot3d import Axes3D #Parameters to set mu_x = 0 variance_x = 3 mu_y = 0 variance_y = 15 #Create grid and multivariate normal x = np.linspace(-10,10,500) y = np.linspace(-10,10,500) X, Y = np.meshgrid(x,y) pos = np.empty(X.shape + (2,)) pos[:, :, 0] = X; pos[:, :, 1] = Y rv = multivariate_normal([mu_x, mu_y], [[variance_x, 0], [0, variance_y]]) #Make a 3D plot fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(X, Y, rv.pdf(pos),cmap='viridis',linewidth=0) ax.set_xlabel('X axis') ax.set_ylabel('Y axis') ax.set_zlabel('Z axis') plt.show() 

Te doy esta ttwig: introduzca la descripción de la imagen aquí

Editar

Una versión más simple está disponible a través de matplotlib.mlab.bivariate_normal. Toma los siguientes argumentos para que no tenga que preocuparse por las matrices matplotlib.mlab.bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0, mux=0.0, muy=0.0, sigmaxy=0.0) Aquí X e Y son nuevamente el resultado de una malla de malla, así que usa esto para recrear la gráfica anterior:

 import numpy as np import matplotlib.pyplot as plt from matplotlib.mlab import bivariate_normal from mpl_toolkits.mplot3d import Axes3D #Parameters to set mu_x = 0 sigma_x = np.sqrt(3) mu_y = 0 sigma_y = np.sqrt(15) #Create grid and multivariate normal x = np.linspace(-10,10,500) y = np.linspace(-10,10,500) X, Y = np.meshgrid(x,y) Z = bivariate_normal(X,Y,sigma_x,sigma_y,mu_x,mu_y) #Make a 3D plot fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_surface(X, Y, Z,cmap='viridis',linewidth=0) ax.set_xlabel('X axis') ax.set_ylabel('Y axis') ax.set_zlabel('Z axis') plt.show() 

Dando introduzca la descripción de la imagen aquí

La siguiente adaptación al código de @ Ianhi anterior devuelve una versión de trazado de contorno de la gráfica 3D anterior.

 import matplotlib.pyplot as plt from matplotlib import style style.use('fivethirtyeight') import numpy as np from scipy.stats import multivariate_normal #Parameters to set mu_x = 0 variance_x = 3 mu_y = 0 variance_y = 15 x = np.linspace(-10,10,500) y = np.linspace(-10,10,500) X,Y = np.meshgrid(x,y) pos = np.array([X.flatten(),Y.flatten()]).T rv = multivariate_normal([mu_x, mu_y], [[variance_x, 0], [0, variance_y]]) fig = plt.figure(figsize=(10,10)) ax0 = fig.add_subplot(111) ax0.contour(rv.pdf(pos).reshape(500,500)) plt.show() 

introduzca la descripción de la imagen aquí