Autor: Luis Fernando Apáez Álvarez
-Curso PyM-
Clase 6: Librería Seaborn-Conceptos intermedios (Parte III)
Fecha: 13 de diciembre del 2022
Con esta clase finalizamos la parte de graficación utilizando la librería Seaborn.
Son un conjunto de gráficos que nos sirven para comparar múltiples gráficos una a lado de la otra utilizando los mismos ejes. Recordemos que en clases anteriores exploramos el objeto de matplolib denominado FacetGrid
, con el cual podíamos tener varios subgráficos en una misma figura. Vimos que las funciones catplot(), relplot(), distplot()
y lmplot()
nos devuelven objetos del tipo FaceGrid
. Por ejemplo, para la función lmplot()
import matplotlib.pyplot as plt
import seaborn as sns
# Cargamos el conjunto de datos
df = sns.load_dataset('iris')
# Realizamos varios diagramas de dispersion (por especie)
# con la recta de regresion
g = sns.lmplot(data=df, x='sepal_width',
y='sepal_length',
col='species')
# Podemos configurar para que no se vea la recta de regresion
g = sns.lmplot(data=df, x='sepal_width',
y='sepal_length',
col='species',
fit_reg=False)
A diferencia de las funcion que hablamos antes, para la función pairplot()
solo será necesario definir las columnas de datos que queremos comparar y no el tipo de gráfico. Por ejemplo:
# Especificamos una lista para el parametro vars
# referente a las variables que queremos considerar:
g = sns.pairplot(data=df, vars=['sepal_length', 'sepal_width'])
notamos que en automático se han creado 4 subgráficos, referentes a diagramas de dispersión entre las variables y a histogramas individuales de las variables, así, con la faceta anterior vemos la relación entre las variables involucradas y su distribución inividual.
En vez de ver solo los diagramas de dispersión, podemos ver los diagramas con las rectas de regresión, para ello establecemos kind='reg'
:
g = sns.pairplot(data=df, vars=['sepal_length', 'sepal_width'],
kind='reg')
Podemos cambiar también los histogramas utilizando el parámetro diag_kind=
. Además, podemos personalizar los gráficos:
# Vemos la distribucion de las variables involucradas por
# especie, asimismo vemos los diagramas de dispersion
# por especie
g = sns.pairplot(data=df, vars=['sepal_length', 'sepal_width'],
kind='reg',
hue='species')
donde vemos que no se muestran los histogramas, más bien la curva de estimación de la distribución de la variables, por especie. Cambiamos a histograma mediante diag_kind=hist
:
g = sns.pairplot(data=df, vars=['sepal_length', 'sepal_width'],
kind='reg',
hue='species',
diag_kind='hist',
# Cambiamos la paleta de color
palette='husl')
Podemos obtener más gráficos si involucramos más variables. Agregamos una tercer variable
g = sns.pairplot(data=df, vars=['sepal_length', 'sepal_width', 'petal_length'],
kind='reg',
hue='species',
# Cambiamos la paleta de color
palette='husl')
Este tipo de gráficos nos permite comparar la distribución de datos entre dos variables, valiéndose de distintos tipos de gráficos para lograr dicho objetivo. Por ejemplo crearemos un gráfico utilizando jointplot()
para las variables de longitud y ancho del sépalo:
g = sns.jointplot(data=df, x='sepal_length', y='sepal_width')
vemos que el gráfico central es un diagrama de dispersión y en los bordes vemos un histograma individual de cada variable involucrada. De tal manera, el gráfico anterior nos muestra la relación entre las variables y la distribución de las mismas. Podemos modificar el gráfico central:
g = sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex')
con el cual vemos con los hexágonos de colores más oscuros mayor concentración de los datos, y para los hexágonos de colores más claros vemos menos concentración de los datos. Por otro lado, jointplot()
admite la adición de gráficos para colocarlos superpuesto. Por ejemplo podemos colocar en el gráfico central un diagrama de dispersión y el gráfico hexagecimal. Para ello:
# entre parentesis colocamos el grafico con centro referente
# al grafico hexagecimal
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex'))\
.plot_joint(sns.scatterplot)
# despues usamos la funcion plot_joint() y colocamos dentro
# la funcion de seaborn referente al grafico que queremos
# superponer:
# superponemos el diagrama de dispersion
# Podemos cambiar el color de los puntos del diagrama de
# dispersion y la transparencia
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex'))\
.plot_joint(sns.scatterplot, color='Red', alpha=0.5)
# podemos cambiar el diagrama de dispersion por
# una curva kde
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex'))\
.plot_joint(sns.kdeplot, color='purple', alpha=0.5)
Sabemos que la curva kde nos muestra la curva de estimación de la densidad de probabilidad, pero como ahora estamos trabajando con dos variables, dicha curva será tridimensional, de modo que lo que vemos en el gráfico anterior es una curva de nivel de dicha función de densidad de la distribución.
Luego, veamos otro ejemplo donde incluimos una gráfico de regresión
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex'))\
.plot_joint(sns.regplot, color='Red')
Podemos sperponer más gráficos
# comenzamos con un grafico hexagonal y uno de regresion
g = ((sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hex'))\
.plot_joint(sns.regplot, color='Red'))\
.plot_joint(sns.kdeplot, color='orange', alpha=0.5)
# luego colocamos la curva de nivel referente a la funcion
# de densidad
O podemos graficar un gráfico de dispersión con las curvas de nivel de la función de densidad por especie.
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='scatter',
hue='species'))\
.plot_joint(sns.kdeplot, color='orange', alpha=0.5)
# En vez del diagrama de dispersion por especie,
# colocamos un solo diagrama de regresion
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='reg'))\
.plot_joint(sns.kdeplot, color='orange', alpha=0.5)
# En vez de reg colocamos hist y obtenemos un mapa de calor
g = (sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hist'))\
.plot_joint(sns.kdeplot, alpha=0.5)
Podremos modificar también los gráficos de los márgenes utilizando marginal_kws=
, a dicho parámetro le debemos pasar un diccionario. Por ejemplo
# Quitamos el relleno de los histogramas
g = sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hist',
marginal_kws=dict(fill=False),
# altura y ancho del grafico
height=5, ratio=3)
g.plot_joint(sns.kdeplot, alpha=0.5)
plt.show()
Podemos cambiar los gráficos marginales utilizando la función plot_marginals()
como sigue
g = sns.jointplot(data=df, x='sepal_length', y='sepal_width',
kind='hist',
# altura y ancho del grafico
height=5, ratio=3)
g.plot_joint(sns.kdeplot, alpha=0.5)
g.plot_marginals(sns.rugplot, color='red', height=0.15)
plt.show()
Si bien en clases anteriores ya hemos indagado sobre la función kdeplot()
referente a la estimación de la curva de densidad de probabilidad de la distribución. Por ejemplo, un gráfico de la curva kde simple con el histograma:
g = sns.displot(data=df, x='sepal_length', kde=True)
O simplemente la curva kde:
g = sns.kdeplot(data=df, x='sepal_length')
# Podemos voltear el grafico colocando y=
# en vez de x=
g = sns.kdeplot(data=df, y='sepal_length')
Si no colocamos un valor para la x=
o y=
y solo pasamos el dataframe, obtenemos la estimación de la curva de densidad para cada variable cuantitativa del dataframe:
# Rellenamos cada curva kde con fill=True
g = sns.kdeplot(data=df, fill=True)
O gráficamos la curva kde para una variable por categoría
g = sns.kdeplot(data=df, x='sepal_length', hue='species')
# Podemos colocar las curvas kde apiladas, o una encima de otra
# configurando multiple='stack'.
# En este caso se apilan para las distribuciones condicionales
g = sns.kdeplot(data=df, x='sepal_length', hue='species', multiple='stack')
# o apilar en cada valor de la cuadricula para las
# distribuciones normalizadas
g = sns.kdeplot(data=df, x='sepal_length', hue='species', multiple='fill')
Podemos graficar la curva ecdf:
g = sns.kdeplot(data=df, x='sepal_length', hue='species',
cumulative=True)
# podemos cambiar a una escala logaritmica
g = sns.kdeplot(data=df, x='sepal_length', hue='species',
log_scale=True)
Así como vimos en la parte de jointplot()
, podemos graficar para una distribución bivariada:
g = sns.kdeplot(data=df, x='sepal_length', y='sepal_width')
# kde bicariada por especies
g = sns.kdeplot(data=df, x='sepal_length', y='sepal_width',
hue='species',
# grafico con relleno
fill=True,
# transparencia
alpha=0.8)
# kde bicariada por especies
g = sns.kdeplot(data=df, x='sepal_length', y='sepal_width',
# grafico con relleno
fill=True,
# cambiamos la paleta de colores
cmap='mako')
# kde bicariada por especies
g = sns.kdeplot(data=df, x='sepal_length', y='sepal_width',
# grafico con relleno
fill=True,
# cambiamos la paleta de colores
cmap='mako',
thresh=0)
donde, con thresh=0
hacemos que la línea de contorno abarque toda la figura.
Otro ejemplo configurando thresh=0
:
g = sns.kdeplot(data=df, x='sepal_length', y='sepal_width', fill=True, thresh=0)