Guía definitiva de mapas de calor en Seaborn con Python

En este tutorial, cubriremos todo lo que necesita saber, desde el uso básico hasta el avanzado de mapas de calor en Seaborn y Python.

Introducción

Un mapa de calor es una técnica de visualización de datos que utiliza el color para mostrar cómo cambia un valor de interés según los valores de otras dos variables.

Por ejemplo, podría usar un mapa de calor para comprender cómo varía la contaminación del aire según la hora del día en un conjunto de ciudades.

Otro caso, quizás más raro, de usar mapas de calor es observar el comportamiento humano: puede crear visualizaciones de cómo las personas usan las redes sociales, cómo cambiaron sus respuestas en las encuestas a lo largo del tiempo, etc. Estas técnicas pueden ser muy poderosas para examinar patrones en el comportamiento, especialmente para instituciones psicológicas que comúnmente envían encuestas de autoevaluación a los pacientes.

Aquí hay dos mapas de calor que muestran las diferencias en cómo dos usuarios usan Twitter:

mapas de calor con seabornw

Estos gráficos contienen todos los componentes principales de un mapa de calor. Fundamentalmente es una cuadrícula de cuadrados de colores donde cada cuadrado, o bin, marca la intersección de los valores de dos variables que se extienden a lo largo de los ejes horizontal y vertical.

En este ejemplo, estas variables son:

  1. La hora del día
  2. El minuto de la hora

Los cuadrados están coloreados según la cantidad de tweets que caen en cada intervalo de horas/minutos. Al lado de la cuadrícula hay una leyenda que nos muestra cómo se relaciona el color con los valores de conteo. En este caso, los colores más claros (o más cálidos) significan más tweets y los más oscuros (o más fríos) significan menos. ¡De ahí el nombre mapa de calor!

Los mapas de calor son más útiles para identificar patrones en grandes cantidades de datos de un vistazo. Por ejemplo, la franja más oscura y fría de la mañana indica que ambos candidatos no tuitean mucho antes del mediodía. Además, el segundo usuario tuitea con mucha más frecuencia que el primer usuario, con una línea de corte más nítida a las 10 a. m., mientras que el primer usuario no tiene una línea tan clara. Esto se puede atribuir a la programación personal durante el día, en la que el segundo usuario suele terminar algún trabajo asignado a las 10 a. m., seguido de consultar las redes sociales y usarlo.

Los mapas de calor suelen ser un buen punto de partida para análisis más sofisticados. Pero también es una técnica de visualización llamativa, lo que la convierte en una herramienta útil para la comunicación.

En este tutorial, le mostraremos cómo crear un mapa de calor como el anterior utilizando la biblioteca Seaborn en Python.

Seaborn es una biblioteca de visualización de datos construida sobre Matplotlib. Juntos, son los líderes de facto cuando se trata de bibliotecas de visualización en Python.

Seaborn tiene una API de mayor nivel que Matplotlib, lo que nos permite automatizar gran parte de la personalización y las pequeñas tareas que normalmente tendríamos que incluir para hacer que los gráficos de Matplotlib sean más adecuados para el ojo humano. También se integra estrechamente con las estructuras de datos de Pandas, lo que facilita el procesamiento previo y la visualización de datos. También tiene muchos gráficos integrados, con valores predeterminados útiles y un estilo atractivo.

En esta guía, cubriremos tres secciones principales:

  1. Preparación de datos
  2. Trazar un mapa de calor
  3. Mejores prácticas y personalización del mapa de calor

¡Empecemos!

Preparación de un conjunto de datos para crear un mapa de calor con Seaborn {#preparación de un conjunto de datos para crear un mapa de calor con Seaborn}

Cargando un conjunto de datos de ejemplo con pandas

Tenga en cuenta: esta guía se escribió con Python 3.8, Seaborn 0.11.0 y Pandas 1.1.2.

Para esta guía, utilizaremos un conjunto de datos que contiene las marcas de tiempo de los tuits publicados por dos de los candidatos presidenciales de EE. UU. de 2020 en ese momento, Joe Biden y Donald Trump, entre enero de 2017 y septiembre de 2020. Una descripción del conjunto de datos y cómo fue creado se puede encontrar en aquí.

¡Un ejercicio divertido en casa podría ser crear su propio conjunto de datos a partir de los tweets propios o de un amigo y comparar sus hábitos de uso de las redes sociales!

Nuestra primera tarea es cargar esos datos y transformarlos en la forma que Seaborn espera, y es fácil para nosotros trabajar con ellos.

Usaremos la biblioteca Pandas para cargar y manipular datos:

1
import pandas as pd

Podemos usar la función read_csv() de Pandas para cargar el conjunto de datos de conteo de tweets. Puede pasar la URL que apunta al conjunto de datos o descargarla y hacer referencia al archivo manualmente:

1
2
3
4
5
data_url = "https://bit.ly/3cngqgL" # or "path/to/biden_trump_tweets.csv"
df = pd.read_csv(data_url, 
                 parse_dates=['date_utc'], 
                 dtype={'hour_utc':int,'minute_utc':int,'id':str}
                )

Siempre vale la pena usar el método head para examinar las primeras filas del DataFrame, para familiarizarse con su forma:

1
df.head()
  id                   username          date_utc                    hour_utc   minute_utc   retweets

0 815422340540547073 realDonaldTrump 2017-01-01 05:00:10+00:00 5 0 27134 1 815930688889352192 realDonaldTrump 2017-01-02 14:40:10+00:00 14 40 23930 2 815973752785793024 realDonaldTrump 2017-01-02 17:31:17+00:00 17 31 14119 3 815989154555297792 realDonaldTrump 2017-01-02 18:32:29+00:00 18 32 3193 4 815990335318982656 realDonaldTrump 2017-01-02 18:37:10+00:00 18 37 7337

Aquí, hemos impreso los primeros 5 elementos en el DataFrame. Primero tenemos el índice de cada fila, seguido del id del tweet, el username del usuario que tuiteó ese tweet, así como información relacionada con el tiempo, como date_utc, hour_utc y minuto_utc.

Finalmente, tenemos el número de retweets al final, que se puede usar para verificar una relación interesante entre el contenido de los tweets y la "atención" que recibió.

Transformar los datos en un marco de datos de formato ancho

Es común encontrar datos de registro como este organizados en forma larga (o ordenada). Esto significa que hay una columna para cada variable y cada fila de datos es una sola observación (valor específico) de esas variables. Aquí, cada tweet es cada variable. Cada fila corresponde a un tweet y contiene datos al respecto.

Pero conceptualmente, un mapa de calor requiere que los datos estén organizados en una forma breve (o ancha). Y, de hecho, la biblioteca de Seaborn requiere que tengamos los datos en este formulario para producir visualizaciones de mapas de calor como las que hemos visto antes.

Los datos de formato ancho tienen los valores de las variables independientes como encabezados de fila y columna, mientras que los valores de la variable dependiente están contenidos en las celdas.

Básicamente, esto significa que estamos usando todas las propiedades que no estamos observando como categorías. Tenga en cuenta que algunas categorías aparecen más de una vez. Por ejemplo, en la tabla original, tenemos algo como:


nombre de usuario hora_utc minuto_utc realDonaldTrump 12 4 realDonaldTrump 13 0 realDonaldTrump 12 4


Usando el principio de categoría, podemos acumular las ocurrencias de ciertas propiedades:


categoría ocurrencias realDonaldTrump | 12 horas | 4 minutos 2 realDonaldTrump | 13 horas | 0 minutos 1


Que finalmente podemos transformar en algo más amigable con el mapa de calor:


horas\minutos 0 1 2 3 4 12 0 0 0 0 2 13 1 0 0 0 0


Aquí, tenemos horas como filas, como valores únicos, así como minutos como columnas. Cada valor en las celdas es el número de ocurrencias de tweets en ese momento. Por ejemplo, aquí podemos ver 2 tweets a las 12:04 y un tweet a las 13:01. Con este enfoque, solo tenemos 24 filas (24 horas) y 60 columnas. Sin embargo, si imaginas esta distribución visualmente, esencialmente es un mapa de calor con números.

En nuestro ejemplo, quiero entender si hay algún patrón en la forma en que los candidatos tuitean en diferentes momentos del día. Una forma de hacerlo es contar los tweets creados en cada hora del día y cada minuto de una hora.

Técnicamente, tenemos 2880 categorías. Cada combinación de hora_utc, minuto_utc y nombre de usuario es una categoría separada, y contamos el número de ocurrencias de tweets para cada una de ellas.

Esta agregación es sencilla con Pandas. La hora y el minuto de creación están disponibles en las columnas hora_utc y minuto_utc. Podemos usar la función groupby() de Pandas para recopilar todos los tweets para cada combinación de nombre de usuario, hora_utc y minuto_utc:

1
g = df.groupby(['hour_utc','minute_utc','username'])

Esto significa que solo las filas que tienen el mismo valor de hora_utc, minuto_utc, nombre de usuario pueden considerarse una ocurrencia de la misma categoría.

Ahora podemos contar el número de tweets en cada grupo aplicando la función nunique() para contar el número de ids únicos. Este método evita el doble conteo de tweets duplicados que podrían estar ocultos en los datos, si no se limpian correctamente de antemano:

1
tweet_cnt = g.id.nunique()

Esto nos da una Serie Pandas con los conteos que necesitamos para trazar el mapa de calor:

1
tweet_cnt.head()
1
2
3
4
5
6
7
hour_utc  minute_utc  username       
0         0           JoeBiden           26
                      realDonaldTrump     6
          1           JoeBiden           16
                      realDonaldTrump    11
          2           JoeBiden            6
Name: id, dtype: int64

Para transformar esto en el DataFrame de formato ancho que necesita Seaborn, podemos usar la función pivot() de Pandas.

Para este ejemplo, será más fácil tomar un usuario a la vez y trazar un mapa de calor para cada uno de ellos por separado. Podemos poner esto en una sola figura o en figuras separadas.

Utilice el elemento de acceso loc[] de Pandas para seleccionar el recuento de tweets de un usuario y luego aplique la función pivot(). Utiliza valores únicos del índice/columnas especificados para formar ejes del DataFrame resultante. Giraremos las horas y los minutos para que el ‘DataFrame’ resultante tenga una forma amplia:

1
jb_tweet_cnt = tweet_cnt.loc[:,:,'JoeBiden'].reset_index().pivot(index='hour_utc', columns='minute_utc', values='id')

Luego eche un vistazo a una sección del DataFrame resultante:

1
jb_tweet_cnt.iloc[:10,:9]

minuto_utc 0 1 2 3 4 5 6 7 8


hora_utc 0 26,0 16,0 6,0 7,0 4,0 24,0 2,0 2,0 9,0 1 24,0 7,0 5,0 6,0 4,0 19,0 1,0 2,0 6,0 2 3,0 3,0 3,0 N/A 5,0 1,0 4,0 8,0 N/A 3 3,0 3,0 3,0 4,0 5,0 1,0 3,0 5,0 4,0 4 1,0 1,0 1,0 2,0 NaN NaN 1,0 1,0 1,0 5 1.0 2.0 N/A N/A N/A 1.0 N/A N/A N/A 6 NaN NaN NaN NaN NaN NaN NaN NaN 10 7,0 2,0 1,0 NaN NaN NaN NaN NaN 11 2.0 5.0 NaN NaN NaN NaN NaN NaN 12 4,0 NaN 1,0 1,0 1,0 NaN 1,0 NaN NaN

Tratamiento de valores perdidos {#tratamiento de valores perdidos}

Podemos ver arriba que nuestros datos transformados contienen valores faltantes. Dondequiera que no haya tweets para una combinación dada de minuto/hora, la función pivot() inserta un valor Not-a-Number (NaN) en el DataFrame.

Además, pivot() no crea una fila (o columna) cuando no hubo ningún tweet durante una hora (o minuto) en particular.

Ver arriba donde faltan las horas 7, 8 y 9.

Esto será algo común que suceda cuando se preprocesen los datos. Es posible que falten datos, que sean de tipos o entradas impares (sin validación), etc.

Seaborn puede manejar estos datos faltantes muy bien, simplemente se trazará sin ellos, omitiendo las horas 7, 8 y 9. Sin embargo, nuestros mapas de calor serán más consistentes e interpretables si completamos los valores faltantes. En este caso, sabemos que los valores perdidos son realmente una cuenta de cero.

Para completar los NaNs que ya se han insertado, use fillna() así:

1
jb_tweet_cnt.fillna(0, inplace=True)

Para insertar las filas que faltan, asegúrese de que todas las combinaciones de horas y minutos aparezcan en el mapa de calor. Vamos a reindexar() el DataFrame para insertar los índices que faltan y sus valores:

1
2
3
4
# Ensure all hours in table
jb_tweet_cnt = jb_tweet_cnt.reindex(range(0,24), axis=0, fill_value=0)
# Ensure all minutes in table
jb_tweet_cnt = jb_tweet_cnt.reindex(range(0,60), axis=1, fill_value=0).astype(int) 

Excelente. Ahora podemos completar nuestra preparación de datos repitiendo los mismos pasos para los tweets de otros candidatos:

1
2
3
4
dt_tweet_cnt = tweet_cnt.loc[:,:,'realDonaldTrump'].reset_index().pivot(index='hour_utc', columns='minute_utc', values='id')
dt_tweet_cnt.fillna(0, inplace=True)
dt_tweet_cnt = dt_tweet_cnt.reindex(range(0,24), axis=0, fill_value=0)
dt_tweet_cnt = dt_tweet_cnt.reindex(range(0,60), axis=1, fill_value=0).astype(int)

Creación de un mapa de calor básico con Seaborn

Ahora que hemos preparado los datos, es fácil trazar un mapa de calor usando Seaborn. Primero asegúrese de haber importado la biblioteca Seaborn:

1
2
import seaborn as sns
import matplotlib.pyplot as plt

También importaremos el módulo PyPlot de Matplotlib, ya que Seaborn se basa en él como motor subyacente. Después de trazar gráficos con las funciones adecuadas de Seaborn, siempre llamaremos a plt.show() para mostrar estos gráficos.

Ahora, como es habitual con Seaborn, trazar datos es tan simple como pasar un DataFrame preparado a la función que nos gustaría usar. Específicamente, usaremos la función heatmap().

Tracemos un mapa de calor simple de la actividad de Trump en Twitter:

1
2
sns.heatmap(dt_tweet_cnt)
plt.show()

mapa de calor de tweets

Y luego la de Biden:

1
2
sns.heatmap(jb_tweet_cnt)
plt.show()

heatmap of tweets

Los mapas de calor producidos con la configuración predeterminada de Seaborn se pueden usar de inmediato. Muestran los mismos patrones que se ven en los gráficos al principio de la guía, pero son un poco más entrecortados, más pequeños y las etiquetas de los ejes aparecen con una frecuencia extraña.

Aparte de eso, podemos ver estos patrones porque Seaborn hace mucho trabajo por nosotros, automáticamente, simplemente llamando a la función heatmap():

  1. Hizo elecciones apropiadas de paleta de colores y escala.
  2. Creó una leyenda para relacionar los colores con los valores subyacentes.
  3. Etiquetó los ejes

Estos valores predeterminados pueden ser lo suficientemente buenos para sus propósitos y examen inicial, como aficionado o científico de datos. Pero a menudo, producir un mapa de calor realmente efectivo requiere que personalicemos la presentación para satisfacer las necesidades de la audiencia.

Echemos un vistazo a cómo podemos personalizar un mapa de calor de Seaborn para producir los mapas de calor que se ven al principio de la guía.

Cómo personalizar un mapa de calor Seaborn

Uso efectivo del color

La característica definitoria de un mapa de calor es el uso del color para representar la magnitud de una cantidad subyacente.

Es fácil cambiar los colores que usa Seaborn para dibujar el mapa de calor especificando el parámetro opcional cmap (mapa de colores). Por ejemplo, aquí se muestra cómo cambiar a la paleta de colores 'mako':

1
2
sns.heatmap(dt_tweet_cnt, cmap="mako")
plt.show()

esquema de color mako para mapas de calor en seaborn

Seaborn proporciona muchas paletas integradas entre las que puede elegir, pero debe tener cuidado de elegir una buena paleta para sus datos y propósito.

Para los mapas de calor que muestran datos numéricos, como el nuestro, las paletas secuenciales como 'rocket' o 'mako' son buenas opciones. Esto se debe a que los colores de estas paletas se han elegido para que sean perceptivamente uniformes. Esto significa que la diferencia que percibimos entre dos colores con nuestros ojos es proporcional a la diferencia entre los valores subyacentes.

El resultado es que al mirar el mapa podemos tener una idea inmediata de la distribución de valores en los datos.

Un contraejemplo demuestra los beneficios de una paleta perceptualmente uniforme y las trampas de una mala elección de paleta. Aquí está el mismo mapa de calor dibujado usando la paleta tab10:

1
2
sns.heatmap(dt_tweet_cnt, cmap="tab10")
plt.show()

mapa de colores tab10 para mapas de calor de seaborn

Esta paleta es una mala elección para nuestro ejemplo porque ahora tenemos que trabajar muy duro para comprender la relación entre los diferentes colores. ¡Ha oscurecido en gran medida los patrones que antes eran obvios!

Esto se debe a que la paleta tab10 utiliza cambios de tono para facilitar la distinción entre categorías. Puede ser una buena opción si los valores de su mapa de calor fueran categóricos.

Si está interesado en los valores altos y bajos de sus datos, puede considerar usar una paleta divergente como coolwarm o icefire, que es un esquema uniforme que resalta ambos extremos.

Para más información sobre la selección de paletas de colores, la documentación de Seaborn tiene alguna orientación útil.

Controlar el efecto de distorsión de los valores atípicos

Los valores atípicos en los datos pueden causar problemas al trazar mapas de calor. De forma predeterminada, Seaborn establece los límites de la escala de colores en el valor mínimo y máximo de los datos.

Esto significa que los valores extremadamente grandes (o pequeños) en los datos pueden hacer que los detalles se oscurezcan. Cuanto más extremos sean los valores atípicos, más lejos estaremos de un paso de coloración uniforme. Hemos visto qué efecto puede tener esto con los diferentes mapas de colores.

Por ejemplo, si agregamos un valor atípico extremo, como 400 ocurrencias de tweets en un solo minuto, ese único valor atípico cambiará la distribución del color y la distorsionará significativamente:

mapa de calor de Seaborn que mitiga el impacto de los valores atípicos

Una forma de manejar valores extremos sin tener que eliminarlos del conjunto de datos es usar el parámetro opcional robusto. Establecer “robusto” en “Verdadero” hace que Seaborn establezca los límites de la escala de colores en los valores de los percentiles 2 y 98 de los datos, en lugar del máximo y el mínimo. Esto, en la gran mayoría de los casos, normalizará la dispersión del color a un estado mucho más utilizable.

Tenga en cuenta que en nuestro ejemplo, esto osciló en la distribución de ocurrencia/color de 0..16, a diferencia de 0..40 de antes. Esto no es ideal, pero es una solución rápida y fácil para valores extremos.

Eso puede traer de vuelta el detalle como muestra el ejemplo de la derecha. Tenga en cuenta que el punto de valor extremo todavía está presente en el gráfico; los valores superiores o inferiores a los límites de la escala de colores se recortan en los colores de los extremos de la escala.

También es posible establecer manualmente los límites de la escala de colores configurando los valores de los parámetros vmin y vmax. Puede ser muy útil si planea tener dos mapas de calor uno al lado del otro y desea garantizar la misma escala de color para cada uno:

1
2
sns.heatmap(tmp, vmin=0, vmax=40)
plt.show()

Composición: clasificación de los ejes para las relaciones de superficie {#composiciónclasificación de los ejes para las relaciones de superficie}

En nuestro ejemplo, los valores que componen los ejes de nuestro mapa de calor, las horas y los minutos, tienen un orden natural. Es importante tener en cuenta que estos son valores discretos, no continuos y que se pueden reorganizar para ayudar a mostrar patrones en los datos.

Por ejemplo, en lugar de tener los minutos en el orden ascendente normal, podríamos optar por ordenarlos en función de qué minuto tiene la mayor cantidad de tweets:

Sorting axes in seaborn heatmap

Esto proporciona una nueva presentación alternativa de los datos de conteo de tweets. Desde el primer mapa de calor, podemos ver que Biden prefiere twittear en cuartos (30, 45, 0 y 15 después de la hora), similar a cómo ciertas personas ajustan el volumen de su TV en incrementos de 5, o cuántas personas tienden a "esperar el momento adecuado" para comenzar a realizar una tarea, generalmente en un número redondo o cuarto.

Por otro lado, no parece haber un minuto favorable en el segundo mapa de calor. Hay una distribución bastante consistente a lo largo de todos los minutos de la hora y no hay muchos patrones que se puedan observar.

En otros contextos, la ordenación o agrupación cuidadosa de las variables categóricas que componen los ejes del mapa de calor puede ser útil para resaltar patrones en los datos y aumentar la densidad de información del gráfico.

Adición de anotaciones de valor

Una desventaja de los mapas de calor es que es difícil hacer comparaciones directas entre valores. Un gráfico de barras o de líneas es una forma mucho más fácil de hacer esto.

Sin embargo, es posible aliviar este problema agregando anotaciones al mapa de calor para mostrar los valores subyacentes. Esto se hace fácilmente en Seaborn configurando el parámetro annot en True, así:

1
2
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], annot=True)
plt.show()

agregando anotaciones de valor al mapa de calor de Seaborn

Hemos recortado los datos en un conjunto más pequeño para que sea más fácil ver y comparar algunos de estos contenedores. Aquí, cada contenedor ahora está anotado con los valores subyacentes, lo que hace que sea mucho más fácil compararlos. Aunque no es tan natural e intuitivo como un gráfico de líneas o de barras, sigue siendo útil.

Trazar estos valores en todo el mapa de calor que tenemos no sería práctico, ya que los números serían demasiado pequeños para leerlos.

Un compromiso útil puede ser agregar anotaciones solo para ciertos valores interesantes. En el siguiente ejemplo, agreguemos una anotación solo para el valor máximo.

Esto se hace creando un conjunto de etiquetas de anotación que se pueden pasar a la función heatmap() de Seaborn a través del parámetro annot. El parámetro annot_kws también se puede usar para controlar aspectos de la etiqueta, como el tamaño de la fuente utilizada:

1
2
3
4
5
6
7
8
# Create data labels, using blank string if under threshold value
M = jb_tweet_cnt.iloc[14:23,25:35].values.max()
labels = jb_tweet_cnt.iloc[14:23,25:35].applymap(lambda v: str(v) if v == M else '')

# Pass the labels to heatmap function
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], annot=labels, annot_kws={'fontsize':16}, fmt='')

plt.show()

anotando solo un valor en el mapa de calor de Seaborn

Puede ser creativo al definir conjuntos de etiquetas personalizados. La única restricción es que los datos que pase para las etiquetas deben tener el mismo tamaño que los datos que está trazando. Además, si sus etiquetas son cadenas, debe pasar el parámetro fmt='' para evitar que Seaborn interprete sus etiquetas como números.

Cuadrículas y cuadrados

Ocasionalmente, ayuda recordarle a su audiencia que un mapa de calor se basa en contenedores de cantidades discretas. Con algunos conjuntos de datos, el color entre dos contenedores puede ser muy similar, lo que crea una textura similar a un degradado que hace que sea más difícil discernir entre valores específicos. El parámetro linewidth y linecolor se pueden usar para agregar líneas de cuadrícula al mapa de calor.

De manera similar, el parámetro ‘cuadrado’ se puede usar para forzar que la relación de aspecto de los cuadrados sea verdadera. Tenga en cuenta que no necesita usar cuadrados para contenedores.

Agreguemos una delgada línea blanca entre cada contenedor para enfatizar que son entradas separadas:

1
2
3
sns.heatmap(jb_tweet_cnt.iloc[14:23,25:35], linewidth=1, linecolor='w', square=True)

plt.show()

añadiendo cuadrículas y forzando cuadrados

En cada uno de estos casos, depende de su juicio si estos cambios estéticos favorecen o no los objetivos de su visualización.

Mapas de calor categóricos en Seaborn

Hay momentos en los que es útil simplificar un mapa de calor poniendo datos numéricos en categorías. Por ejemplo, podríamos agrupar los datos de conteo de tweets en solo tres categorías “alto”, “medio” y “bajo”, en lugar de un rango numérico como “0..40”.

Desafortunadamente, en el momento de escribir este artículo, Seaborn no tiene la capacidad integrada de producir mapas de calor para datos categóricos como este, ya que espera una entrada numérica. Aquí hay un fragmento de código que muestra que es posible "falsificarlo" con una pequeña paleta y pirateando la barra de colores.

Aunque esta es una circunstancia en la que es posible que desee considerar el mérito de otros paquetes de visualización que tienen estas funciones integradas.

Usaremos la ayuda de Matplotlib, el motor subyacente debajo de Seaborn, ya que tiene muchas opciones de personalización de bajo nivel y tenemos acceso completo a él. Aquí, podemos "hackear" la leyenda de la derecha para mostrar los valores que nos gustaría:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1,1,figsize=(18,8))
my_colors=[(0.2,0.3,0.3),(0.4,0.5,0.4),(0.1,0.7,0),(0.1,0.7,0)]

sns.heatmap(dt_tweet_cnt, cmap=my_colors, square=True, linewidth=0.1, linecolor=(0.1,0.2,0.2), ax=ax)

colorbar = ax.collections[0].colorbar
M=dt_tweet_cnt.max().max()
colorbar.set_ticks([1/8*M,3/8*M,6/8*M])
colorbar.set_ticklabels(['low','med','high'])

plt.show()

leyenda del mapa de calor categórico seaborn

Preparación de mapas de calor para la presentación

Un par de últimos pasos para dar los toques finales a tu mapa de calor.

Uso del contexto de Seaborn para controlar la apariencia

La función set_context() proporciona una forma útil de controlar algunos de los elementos de la trama sin cambiar su estilo general. Por ejemplo, puede ser una forma conveniente de personalizar los tamaños y las familias de las fuentes.

Hay varios contextos preestablecidos disponibles:

1
sns.set_context("notebook", font_scale=1.75, rc={"lines.linewidth": 2.5, 'font.family':'Helvetica'})

Uso de subgráficos para controlar el diseño de los mapas de calor {#uso de subgráficos para controlar el diseño de los mapas de calor}

El paso final en la creación de nuestro mapa de calor de conteo de tweets es poner los dos gráficos uno al lado del otro en una sola figura para que sea fácil hacer comparaciones entre ellos.

Podemos usar la función subplot() de matplotlib.pyplot para controlar el diseño de los mapas de calor en Seaborn. Esto le dará el máximo control sobre el gráfico final y permitirá una fácil exportación de la imagen.

Crear subtramas usando Matplotlib es tan fácil como definir su forma (2 subtramas en 1 columna en nuestro caso):

1
2
3
4
5
6
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12,12))
sns.heatmap(jb_tweet_cnt, ax=ax1)
sns.heatmap(dt_tweet_cnt, ax=ax2)

plt.show()

subtrazado de mapas de calor con seaborn

Esto es esencialmente todo, aunque carece de algunos de los estilos que hemos visto al principio. Reunamos muchas de las personalizaciones que hemos visto en la guía para producir nuestro gráfico final y exportarlo como un .png para compartir:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1, figsize=(24,12))

for i,d in enumerate([jb_tweet_cnt,dt_tweet_cnt]):
   
    labels = d.applymap(lambda v: str(v) if v == d.values.max() else '')
    sns.heatmap(d,
                cmap="viridis",  # Choose a squential colormap
                annot=jb_labels, # Label the maximum value
                annot_kws={'fontsize':11},  # Reduce size of label to fit
                fmt='',          # Interpret labels as strings
                square=True,     # Force square cells
                vmax=40,         # Ensure same 
                vmin=0,          # color scale
                linewidth=0.01,  # Add gridlines
                linecolor="#222",# Adjust gridline color
                ax=ax[i],        # Arrange in subplot
               )
    
ax[0].set_title('@JoeBiden')
ax[1].set_title('@realDonaldTrump')
ax[0].set_ylabel('Hour of Day')
ax[1].set_ylabel('Hour of Day')
ax[0].set_xlabel('')
ax[1].set_xlabel('Minute of Hour')
plt.tight_layout()
plt.savefig('final.png', dpi=120)

heatmap

Conclusión

En esta guía, analizamos los mapas de calor y cómo crearlos con Python y la biblioteca de visualización de Seaborn.

La fuerza de los mapas de calor está en la forma en que utilizan el color para transmitir la información; en otras palabras, facilita que cualquier persona vea patrones amplios de un vistazo.

Hemos visto cómo para hacer esto tenemos que hacer selecciones cuidadosas de paleta de colores y escala. También hemos visto que hay varias opciones disponibles para personalizar un mapa de calor usando Seaborn para enfatizar aspectos particulares del gráfico. Estos incluyen anotaciones, agrupar y ordenar ejes categóricos y diseño.

Como siempre, se requiere el juicio editorial por parte del visualizador de datos para elegir las personalizaciones más apropiadas para el contexto de la visualización.

Hay muchas variantes del mapa de calor que le pueden interesar estudiar, incluidos los mapas de calor radiales, los gráficos de mosaico o los gráficos matriciales.