python - real - ¿Cómo crear un diagrama de densidad en matplotlib?
matplotlib python (4)
Cinco años después, cuando busqué "cómo crear una gráfica de densidad de kernel usando Python", ¡este hilo aún aparece en la parte superior!
Hoy en día, una forma mucho más fácil de hacer esto es usar seaborn , un paquete que proporciona muchas funciones de trazado convenientes y una buena gestión de estilo.
import numpy as np
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.set_style(''whitegrid'')
sns.kdeplot(np.array(data), bw=0.5)
En RI puede crear el resultado deseado haciendo:
data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8),
rep(4.5, 3), rep(5.5, 1), rep(6.5, 8))
plot(density(data, bw=0.5))
En python (con matplotlib) lo más cercano que conseguí fue con un simple histograma:
import matplotlib.pyplot as plt
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
plt.hist(data, bins=6)
plt.show()
También probé el parámetro norma = verdadero, pero no pude obtener nada más que tratar de ajustar un gaussiano al histograma.
Mis últimos intentos fueron alrededor de scipy.stats
y gaussian_kde
, siguiendo ejemplos en la web, pero hasta ahora no he tenido éxito.
Sven ha mostrado cómo usar la clase gaussian_kde
de Scipy, pero notará que no se parece mucho a lo que generó con R. Esto se debe a que gaussian_kde
intenta inferir el ancho de banda automáticamente. Puede jugar con el ancho de banda de una manera cambiando la función covariance_factor
de la clase gaussian_kde
. Primero, esto es lo que obtienes sin cambiar esa función:
Sin embargo, si uso el siguiente código:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = gaussian_kde(data)
xs = np.linspace(0,8,200)
density.covariance_factor = lambda : .25
density._compute_covariance()
plt.plot(xs,density(xs))
plt.show()
yo obtengo
que es bastante similar a lo que obtienes de R. ¿Qué he hecho? gaussian_kde
usa una función modificable, covariance_factor
para calcular su ancho de banda. Antes de cambiar la función, el valor devuelto por covariance_factor para estos datos era de aproximadamente .5. Bajar esto bajó el ancho de banda. Tuve que llamar a _compute_covariance
después de cambiar esa función para que todos los factores se calcularan correctamente. No es una correspondencia exacta con el parámetro bw de R, pero es de esperar que te ayude a ir en la dirección correcta.
Tal vez intente algo como:
import matplotlib.pyplot as plt
import numpy
from scipy import stats
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
density = stats.kde.gaussian_kde(data)
x = numpy.arange(0., 8, .1)
plt.plot(x, density(x))
plt.show()
Puede reemplazar fácilmente gaussian_kde()
por una estimación de densidad de kernel diferente.
Opción 1:
Utilice el diagrama de marco de datos de pandas
(construido sobre matplotlib
):
import pandas as pd
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
pd.DataFrame(data).plot(kind=''density'') # or pd.Series()
Opcion 2:
Use distplot
de seaborn
:
import seaborn as sns
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
sns.distplot(data, hist=False)