Representaciones gráficas con Seaborn

Estándar

Dibujar gráficas es una parte esencial del análisis de datos; no sólo para presentar los resultados finales, sino también para entender mejor lo que tenemos entre manos. Como se vió en la entrada anterior, Pandas tiene un subsistema de representación gráfica muy práctico. Sin embargo, a veces los gráficos simples que produce este subsistema son insuficientes para una visualización más completa y profunda. Aquí es donde entra Seaborn, dándonos una serie de representaciones gráficas orientadas a la visualización de conjuntos de datos complejos y con especial atención a la claridad.

Usaremos los datos de consumo de diferentes modelos de coche que usamos en la entrada anterior.

In [1]:
%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

fedata = pd.read_csv('mpg.csv', index_col=0)
fedata['autovia'] = 235.215/fedata['hwy']
fedata['ciudad'] = 235.215/fedata['cty']
fedata = fedata.drop(['cty','hwy'], axis=1)

Seaborn nos permite explorar cada variable de forma individual con funciones como kdeplot(), que representa una aproximación continua a la distribución de densidad basada en los valores de los datos:

In [2]:
sns.kdeplot(fedata['autovia'])
sns.kdeplot(fedata['ciudad'])
plt.show()

Con esta gráfica, podemos decir que en términos generales, el consumo en ciudad es mayor que el consumo en autovía, dado que hay una mayor densidad en valores altos. Pero podemos querer saber más. Por ejemplo, ¿los coches que tienen un menor consumo en autovía lo tienen también en ciudad? ¿o bien es que optimizar un coche para tener mayor autonomía en autovía implica que empeora su comportamiento en ciudad? (vamos a suponer que no sabemos la respuesta a estas preguntas). Para ello, necesitamos hacer un análisis bivariante usando funciones como jointplot() que dibuja una nube de puntos y además la distribución de cada variable:

In [3]:
sns.jointplot(fedata['ciudad'],fedata['autovia'])
plt.show()

Vemos que sin lugar a dudas, hay una alta correlación entre ambas variables. Podemos estar casi seguros de que un mayor consumo en autovía implica un mayor consumo en ciudad.

En la entrada anterior empezamos buscando la relación entre el número de cilindros y el consumo medio. Nos dio la idea de que a mayor número de cilindros, mayor era el consumo. Pero eso reflejaba sólo el comportamiento de la media. Con Seaborn podemos ver esta relación de forma más detallada. Dibujaremos una gráfica de muestras de consumo en ciudad contra consumo en autovía clasificando por número de cilindros usando para ello la función FacetGrid(). FacetGrid() nos proporciona una cuadrícula de gráficas con datos clasificados según una o dos variables categóricas. Sobre esa cuadrícula, aplicamos una función de Matplotlib mediante map() para dibujar la gráfica que buscamos:

In [4]:
grid = sns.FacetGrid(fedata, col='cyl')
grid.map(plt.scatter,'ciudad','autovia')
plt.show()

Podemos ver que, en general, a mayor número de cilindros, mayor es el consumo; pero esto no es una verdad absoluta. Hay coches con 8 cilindros que consumen menos que coches con 4. Con una minúscula modificación, podemos ver aún más detalles. Muchas funciones de Seaborn admiten un parámetro hue que separa los datos por clase. En nuestro caso, es la segunda clasificación después de haber usado FacetGrid

In [5]:
grid = sns.FacetGrid(fedata, col='cyl', hue='class')
grid.map(plt.scatter,'ciudad','autovia').add_legend()
plt.show()

Vemos que hay clases que en general muestran un mejor comportamiento (compacts, subcompacts) y otras que tienen un consumo generalmente mayor (pickup).

FacetGrid() tiene aún una dimensión más que nos permite una tercera clasificación usando el parámetro row:

In [6]:
grid = sns.FacetGrid(fedata, col='cyl', row='year', hue='class')
grid.map(plt.scatter,'ciudad','autovia').add_legend()
plt.show()

Seaborn incluye funciones aún más sofisticadas que la simple representación de datos. Volviendo a la búsqueda de una relación entre los valores sin clasificar de consumo en ciudad y autovía, podemos mejorar la visualización usando regplot(). Obtenemos la nube de puntos y además una aproximación lineal a la misma.

In [7]:
sns.regplot('ciudad','autovia',fedata)
plt.show()

Para terminar esta entrada, veremos una función que nos permite ver rápidamente las relaciones entre las variables de un DataFrame. Se trata de la función PairGrid, que muestra una gráfica para cada par de columnas.

In [8]:
grid = sns.PairGrid(fedata)
grid.map(plt.scatter)
plt.show()

Una abreviación de lo anterior es pairplot, que además hace un uso mejor de la diagonal:

In [9]:
sns.pairplot(fedata)
plt.show()

Algunas referencias interesantes para ver lo que ofrece Seaborn son el tutorial, la galería de ejemplos y la referencia de la API. Hay muchos otros tipos de representación que ni siquiera hemos mencionado aquí. Seaborn es especialmente potente usado en un flujo de trabajo basado en Pandas. Se puede usar sin él, pero su utilidad se reduce dramáticamente. No es una librería gráfica de propósito general.

2 comentarios en “Representaciones gráficas con Seaborn

  1. Federico

    Muchisimas gracias, soy profesor de FP, y estoy estudiando un Master en Ingenieria Infomática.
    Estoy con una práctica de IA, y me has salvado la vida.

    Muchisimas gracias

Responder a Emil Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *