GRÁFICOS PARA VISUALIZAR SERIES DE TIEMPO

VISUALIZAR SERIES DE TIEMPO

Una serie temporal es una secuencia de observaciones de una variable registradas en puntos específicos en el tiempo.

A diferencia de otros datos, aquí las observaciones no son independientes: están ordenadas y cada valor tiene un “antes” y un “después”.

VISUALIZAR SERIES DE TIEMPO

Para visualizar este tipo de datos, se suelen utilizar gráficos de líneas, en los que se conectan las observaciones individuales entre sí para resaltar el orden temporal.

Las líneas no agregan información nueva: simplemente conectan los datos existentes para hacer visible su evolución en el tiempo y, así, detectar patrones y comportamientos estacionales.

VISUALIZAR SERIES DE TIEMPO (🔗)

Para ejemplificar, trabajaremos con el dataset data_internet.csv del Banco Mundial, que contiene información acerca del porcentaje de personas con acceso a Internet a lo largo del tiempo en una serie de países.

Previamente, realizaremos tareas de limpieza y un filtrado de información para considerar sólo los años a partir de 1990 y los datos correspondientes a los países que se encuentran en lista_paises:

lista_paises = ['Iceland', 'Norway', 'United Kingdom', 'Japan', 'Canada', 
'Germany', 'New Zealand', 'France', 'Israel', 'Argentina', 'United States', 
'Chile', 'Italy', 'Brazil', 'Mexico', 'South Africa', 'China', 'Algeria', 
'India', 'Kenia']

VISUALIZAR SERIES DE TIEMPO

Luego de realizadas las tareas de limpieza y adecuación, las primeras filas del dataset lucen de la siguiente manera:

1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 ... 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021
Country Name
Argentina 0.000 0.000000 0.002993 0.029527 0.043706 0.086277 0.141955 0.280340 0.830767 3.284482 ... 55.80 59.90 64.700000 68.043064 70.968981 74.294907 77.700000 79.946952 85.514386 87.150707
Brazil 0.000 0.003288 0.012946 0.025498 0.037673 0.105138 0.450789 0.786079 1.477875 2.038732 ... 48.56 51.04 54.551002 58.327952 60.872540 67.471285 70.434283 73.912440 81.342694 80.689893
Canada 0.361 0.570386 0.915981 1.184558 2.378694 4.163525 6.760240 15.072357 24.897400 36.186440 ... 83.00 85.80 87.120000 90.000000 91.160000 92.701372 94.640000 91.912897 92.300000 92.834017

3 rows × 32 columns

VISUALIZAR SERIES DE TIEMPO

Como primer ejemplo, supongamos que queremos construir un gráfico para visualizar la evolución del porcentaje de acceso a Internet en Argentina durante el periodo 1990-2021. Lo primero es filtrar esa información y darle forma de DataFrame.

data_argentina = data_internet_filtrado.loc['Argentina'].reset_index().rename(columns = {'index' : 'anio', 'Argentina' : 'porcentaje'})
data_argentina.head()
anio porcentaje
0 1990 0.000000
1 1991 0.000000
2 1992 0.002993
3 1993 0.029527
4 1994 0.043706

VISUALIZAR SERIES DE TIEMPO

Teniendo en cuenta que la columna anio es de tipo object, la transformamos en int64 para poder realizar luego algunas modificaciones de escala en el gráfico:

data_argentina['anio'] = pd.to_numeric(data_argentina['anio'])
data_argentina.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 32 entries, 0 to 31
Data columns (total 2 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   anio        32 non-null     int64  
 1   porcentaje  32 non-null     float64
dtypes: float64(1), int64(1)
memory usage: 644.0 bytes

VISUALIZAR SERIES DE TIEMPO

Luego, utilizamos la función lineplot() de Seaborn para representar estos datos en la forma de un gráfico de líneas:

sns.lineplot(x = 'anio', y = 'porcentaje', data = data_argentina);

VISUALIZAR SERIES DE TIEMPO

Sobre el gráfico anterior, podemos agregar los datos individuales en la forma de puntos seteando el parámetro marker = 'o':

sns.lineplot(x = 'anio', y = 'porcentaje', marker = 'o', data = data_argentina)
plt.title('Evolución del % de acceso a Internet en Argentina\n en el periodo 1990-2021');

¿Qué observamos?

VISUALIZAR SERIES DE TIEMPO

Supongamos ahora que queremos construir un gráfico para comparar la evolución del porcentaje de acceso a Internet en Argentina, India y Estados Unidos en el periodo 1990-2021. Lo primero es filtrar esa información y darle forma de DataFrame en formato largo:

data_paises = data_internet_filtrado.loc[['Argentina', 'India', 'United States']].reset_index().melt(id_vars = 'Country Name', var_name = 'anio', value_name = 'porcentaje')
data_paises.head(3)
Country Name anio porcentaje
0 Argentina 1990 0.000000
1 India 1990 0.000000
2 United States 1990 0.784729

VISUALIZAR SERIES DE TIEMPO

Podemos representar las observaciones correspondientes a cada país, seteando el parámetro hue = 'Country Name' dentro de sns.lineplot():

sns.lineplot(x = 'anio', y = 'porcentaje', hue = 'Country Name', marker = 'o', data = data_paises);

¿Qué diferencias pueden observarse en la evolución del % de acceso a Internet entre los tres países considerados?

INCORPORAR A LOS DEMÁS PAÍSES

Hasta ahora analizamos la evolución de uno o pocos países mediante gráficos de líneas.

Sin embargo, si quisiéramos incluir a todos los países simultáneamente (todos los seleccionados en lista_paises) este tipo de gráfico pierde efectividad: las líneas se superponen y resulta difícil seguir cada trayectoria individual.

En este contexto, necesitamos una nueva forma de representar la información.

print(f'El total de países filtrados es: {len(lista_paises)}')
El total de países filtrados es: 20

EL HEATMAP

El heatmap consiste en la representación gráfica de una matriz de datos, en la que se utiliza una escala de colores para mostrar la magnitud de los valores/observaciones de una variable cuantitativa.

Aunque esta visualización dificulta determinar los valores exactos que se muestran, hace un excelente trabajo al resaltar tendencias generales. Es decir, pasamos de seguir trayectorias individuales a observar patrones globales.

EL HEATMAP

Para construir un heatmap con los datos del porcentaje de acceso a Internet de los 20 países entre los años 1990 y 2021, utilizaremos la función heatmap() de la librería Seaborn. Esta función representa gráficamente la matriz de datos, asignando colores a cada celda según el valor del porcentaje de acceso a Internet correspondiente a cada país y año.

Así luce el heatmap construido a partir de la matriz de datos:

EL HEATMAP

Este es el código que se utilizó para construir el gráfico de la slide anterior, que incluye el uso de la paleta magma (cmap = 'magma') y modificaciones en los títulos de los ejes y de la escala de colores.

ax = sns.heatmap(data_internet_filtrado, cmap = 'magma', cbar_kws={'label': 'Porcentaje de acceso a internet (%)'})
plt.xlabel('Año', fontweight = 'bold')
plt.ylabel('País', fontweight = 'bold')
cbar = ax.collections[0].colorbar
cbar.ax.yaxis.label.set_fontweight('bold')
plt.show()

EL HEATMAP

Una posible mejora del gráfico anterior consiste en reordenar los países (eje \(y\)) para facilitar la comparación. En este sentido, podemos organizarlos según el momento en que alcanzan cierto nivel de acceso.

🤓 Como ejercicio, modificar el heatmap construido para que los países se ordenen según el año en que al menos el 20% de su población accedió a Internet.

Si bien este valor es arbitrario, permite realizar una mejor comparación del ritmo de adopción de Internet entre países.

Este debería ser el resultado:

GRÁFICOS PARA VISUALIZAR ASOCIACIONES ENTRE VARS. CUANTITATIVAS

Algunas clases atrás, utilizamos un scatterplot para representar, en forma conjunta, las observaciones de las variables flipper_length y body_mass del dataset de los pingüinos del archipiélago Palmer:

data_penguins = sns.load_dataset('penguins')

sns.scatterplot(x = 'body_mass_g', y = 'flipper_length_mm', data = data_penguins);

VISUALIZAR ASOCIACIONES ENTRE VARS. CUANTITATIVAS

El dataset incluye varias variables cuantitativas, por lo que deberíamos realizar un scatterplot diferente por cada par de variables que quisiéramos estudiar 🙄.

Para resolver este problema, podemos utilizar matrices de scatterplots, que permiten visualizar múltiples relaciones simultáneamente. La función pairplot() de Seaborn facilita la construcción de este tipo de gráficos.

sns.pairplot(vars = ['bill_length_mm','bill_depth_mm',
                                'flipper_length_mm', 'body_mass_g'], data = data_penguins);

El resultado es una matriz de scatterplots, uno para cada combinación posible de las variables cuantitativas seleccionadas. En la diagonal, se muestra un histograma para visualizar la distribución individual de las observaciones de cada una de ellas.

Si seteamos el parámetro hue = 'species' hacemos visible el hecho de que, en ciertos casos, existen diferencias marcadas entre las especies Adelie, Chinstrap y Gentoo.

La diagonal muestra ahora gráficos de densidad para cada variable individual según la especie.

CORRELOGRAMA

Un correlograma es una representación gráfica de la matriz de correlación entre variables cuantitativas.

Podemos construirlo generando la matriz de correlación de nuestros datos y luego ploteándola con la función heatmap() de la librería Seaborn.

CORRELOGRAMA

# Generamos la matriz de correlación
matriz = data_penguins[['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g']].corr()

# Construimos el heatmap
sns.heatmap(matriz, annot = True);

CORRELOGRAMA

El gráfico anterior es la base de un correlograma, pero todavía tenemos algunas modificaciones importantes para hacerle para que sea adecuado.

En primer lugar, es fundamental utilizar una escala de colores divergente, la cual resulta de la combinación de dos escalas secuenciales unidas en un punto medio común, que generalmente se representa con un color claro. Este tipo de escala es ideal cuando necesitamos visualizar la desviación de los valores de los datos en una de dos direcciones con respecto a un punto medio neutral (en nuestro caso, r = 0).

CORRELOGRAMA

EJEMPLOS DE ESCALAS DIVERGENTES

  1. vlag
  1. coolwarm
  1. BrBG
  1. RdYlGn

CORRELOGRAMA

EJEMPLOS DE ESCALAS DIVERGENTES

  1. seismic
  1. bwr
  1. Definidas manualmente
superior = sns.color_palette('Reds', 25)
inferior = sns.color_palette('Blues_r', 25)
sns.blend_palette(inferior + superior, n_colors = 25, as_cmap = True)

CORRELOGRAMA

Podemos configurar la paleta dentro del parámetro cmap de sns.heatmap() y setear sus límites incluyendo vmin = -1 y vmax = 1. Por ejemplo, con BrBG:

sns.heatmap(matriz, annot = True, cmap = 'BrBG', vmin = -1, vmax = 1);

CORRELOGRAMA

La última modificación importante es agregar un título a la escala de colores para indicar qué representan los valores.

sns.heatmap(matriz, annot = True, cmap = 'BrBG', vmin = -1, vmax = 1, cbar_kws = dict(label = 'r de Pearson'));

CORRELOGRAMA

En el gráfico anterior, los colores verdes más fuertes se asocian con correlaciones lineales positivas más intensas, mientras que las tonalidades marrones más fuertes indican correlaciones lineales inversas más intensas.

¡IMPORTANTE! Si bien los correlogramas muestran información relevante sobre las asociaciones entre variables cuantitativas, al mismo tiempo ocultan la existencia de patrones importantes en los datos y pueden llevarnos a sacar conclusiones incorrectas. Por este motivo, siempre es conveniente complementarlos con una matriz de scatterplots y analizar si tiene sentido informar coeficientes de correlación lineales.

VISUALIZAR 3 VARIABLES CUANTITATIVAS

En los scatterplots que presentamos hasta aquí, se incorporaba la información de dos variables cuantitativas, mapeadas en los ejes cartesianos.

Cuando surgió el interés en incluir una variable cualitativa, la representamos mediante una escala de colores.

¿Qué ocurre si queremos incorporar una tercera variable que también sea cuantitativa? ¿Qué opciones tenemos?

BUBBLE CHART

Un bubble chart es una extensión del scatterplot en la que se incorpora una tercera variable cuantitativa mediante el tamaño de los puntos.

De esta forma, dos variables se representan en los ejes y una tercera variable se codifica a través del tamaño de cada punto

Este tipo de gráfico permite visualizar tres variables simultáneamente en un mismo plano.

BUBBLE CHART

sns.scatterplot(x = 'body_mass_g', y = 'flipper_length_mm', size = 'bill_length_mm', data = data_penguins);

BUBBLE CHART

Algunas limitaciones ⚠️

Si bien podemos representar una tercera variable mediante el tamaño de los puntos, esto presenta algunas dificultades:

  • las diferencias en tamaño son más difíciles de percibir que las diferencias en posición, por lo que comparar valores resulta menos preciso

  • se combinan distintos tipos de escalas visuales (posición y tamaño/área), que no se perciben con la misma claridad

  • pequeñas diferencias en los datos pueden traducirse en cambios casi imperceptibles en el tamaño de los puntos

¿ENTONCES QUÉ HACEMOS?

En lugar de incorporar más variables en un mismo gráfico, muchas veces es preferible:

  • utilizar múltiples visualizaciones más simples

  • representar las relaciones de a pares (por ejemplo, con matrices de scatterplots)

  • priorizar el uso de la posición, que es el canal visual más preciso