Mapa de calor en matplotlib

Mapa de calor con imshow

En matplotlib puedes utilizar la función imshow para crear un mapa de calor, también llamado heat map en inglés. Para ello tan solo es necesario pasar un array de (N, M) dimensiones a la función, donde la primera dimensión define las filas y la segunda las columnas del mapa de calor.

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Mapa de calor
fig, ax = plt.subplots()
ax.imshow(data)
# plt.show()

Mapa de calor en matplotlib

Etiquetas de los grupos

Para agregar etiquetas a las marcas de los ejes con los grupos puedes utilizar las funciones set_xticks y set_yticks, como se muestra a continuación.

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Etiquetas
xlabs = ["G1", "G2", "G3", "G4",
         "G5", "G6", "G7", "G8"]
ylabs = ["A", "B", "C", "D",
         "E", "F", "G", "H"]
         
# Mapa de calor
fig, ax = plt.subplots()
ax.imshow(data)

# Agregar las etiquetas
ax.set_xticks(np.arange(len(xlabs)), labels = xlabs)
ax.set_yticks(np.arange(len(ylabs)), labels = ylabs)
# plt.show()

Marcas de los ejes de un mapa de calor en Python

Rotar las etiquetas de las marcas de los ejes

Si agregas etiquetas a las marcas del eje X y las etiquetas son muy largas no se leerán bien. En este escenario, puedes rotar las etiquetas como se muestra en el siguiente ejemplo para poder leerlas correctamente.

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Etiquetas
xlabs = ["G1", "G2", "G3", "G4",
         "G5", "G6", "G7", "G8"]
ylabs = ["A", "B", "C", "D",
         "E", "F", "G", "H"]
         
# Mapa de calor
fig, ax = plt.subplots()
ax.imshow(data)

# Agregar las etiquetas
ax.set_xticks(np.arange(len(xlabs)), labels = xlabs)
ax.set_yticks(np.arange(len(ylabs)), labels = ylabs)

# Rotar las etiquetas del eje X
plt.setp(ax.get_xticklabels(), rotation = 40,
         ha = "right", rotation_mode = "anchor")
# plt.show()

Rotar las etiquetas de las marcas de los ejes en matplotlib

Personalización del color

Por defecto, la función imshow utiliza la paleta de color viridis, pero puedes utilizar cualquier otra pasándola al argumento cmap. En el siguiente ejemplo estamos utilizando la paleta de colores llamada "Blues".

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))
         
# Mapa de calor
fig, ax = plt.subplots()
ax.imshow(data, cmap = "Blues")

# plt.show()

Paleta de colores de un mapa de calor hecho con matplotlib

Agregar los valores a cada celda

También puedes agregar los valores a cada celda del mapa de calor creado con matplotlib. Para ello tendrás que hacer un bucle que recorra tanto las filas como las columnas y agregar cada texto con la función text. En el siguiente código los valores se centran y se colorean de blanco, pero puedes personalizarlos como quieras.

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Etiquetas
xlabs = ["G1", "G2", "G3", "G4",
         "G5", "G6", "G7", "G8"]
ylabs = ["A", "B", "C", "D",
         "E", "F", "G", "H"]
         
# Mapa de calor
fig, ax = plt.subplots()
ax.imshow(data)

# Agregar las etiquetas
ax.set_xticks(np.arange(len(xlabs)), labels = xlabs)
ax.set_yticks(np.arange(len(ylabs)), labels = ylabs)

# Agregar los valores a cada celda
for i in range(len(xlabs)):
    for j in range(len(ylabs)):
        text = ax.text(j, i, round(data[i, j], 1),
                       ha = "center", va = "center", color = "w")

# plt.show()

Mapa de calor con textos en las celdas en matplotlib

Agregar una leyenda

Los mapas de calor generalmente tienen una leyenda con forma de barra para interpretar mejor los colores de las celdas. Puedes agregar una a tu mapa de calor de matplotlib con figure.colorbar.

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))
         
# Mapa de calor
fig, ax = plt.subplots()
im = ax.imshow(data)

# Agregar la leyenda
cbar = ax.figure.colorbar(im, ax = ax)
cbar.ax.set_ylabel("Color bar", rotation = -90, va = "bottom")

# plt.show()

Heat map con leyenda en matplotlib

Funcióm heatmap en matplotlib

Los ejemplos anteriores muestran cómo crear un mapa de calor utilizando matplotlib, pero se requiere mucho código para personalizar los gráficos. Si quieres crear mapas de calor de manera más rápida puedes utilizar la siguiente función que aparece en la documentación oficial de matplotlib:

def heatmap(data, row_labels, col_labels, ax = None,
            cbar_kw = {}, cbarlabel = "", **kwargs):

    if not ax:
      ax = plt.gca()

    im = ax.imshow(data, **kwargs)

    cbar = ax.figure.colorbar(im, ax = ax, **cbar_kw)
    cbar.ax.set_ylabel(cbarlabel, rotation = -90, va = "bottom")

    ax.set_xticks(np.arange(data.shape[1]), labels = col_labels)
    ax.set_yticks(np.arange(data.shape[0]), labels = row_labels)

    ax.tick_params(top = True, bottom = False,
                   labeltop = True, labelbottom = False)

    plt.setp(ax.get_xticklabels(), rotation = -30, ha = "right",
             rotation_mode = "anchor")

    ax.spines[:].set_visible(False)

    ax.set_xticks(np.arange(data.shape[1] + 1) - 0.5, minor = True)
    ax.set_yticks(np.arange(data.shape[0] + 1) - 0.5, minor = True)
    ax.grid(which = "minor", color = "w", linestyle = '-', linewidth = 3)
    ax.tick_params(which =  "minor", bottom = False, left = False)

    return im, cbar


def annotate_heatmap(im, data = None, valfmt="{x:.2f}",
                     textcolors = ("black", "white"),
                     threshold = None, **textkw):

    if not isinstance(data, (list, np.ndarray)):
        data = im.get_array()

    if threshold is not None:
        threshold = im.norm(threshold)
    else:
        threshold = im.norm(data.max())/2.

    kw = dict(horizontalalignment = "center",
              verticalalignment = "center")
    kw.update(textkw)

    if isinstance(valfmt, str):
        valfmt = matplotlib.ticker.StrMethodFormatter(valfmt)

    texts = []
    for i in range(data.shape[0]):
        for j in range(data.shape[1]):
            kw.update(color=textcolors[int(im.norm(data[i, j]) > threshold)])
            text = im.axes.text(j, i, valfmt(data[i, j], None), **kw)
            texts.append(text)

    return texts

Ejemplo con la función heatmap de matplotlib

La función heatmap permite crear mapas de calor en matplotlib. Al utilizar esta función tan solo tendrás que pasar tus datos a data y las etiquetas de los grupos a row_labels y col_labels para las etiquetas de filas y columnas, respectivamente. Además, puedes personalizar la paleta de colores con cmap y agregar un título a la leyenda con cbarlabel.

La función heatmap en matplotlib

import numpy as np
import matplotlib.pyplot as plt

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Etiquetas
xlabs = ["G1", "G2", "G3", "G4",
         "G5", "G6", "G7", "G8"]
ylabs = ["A", "B", "C", "D",
         "E", "F", "G", "H"]
         
# Mapa de calor
fig, ax = plt.subplots()
heatmap(data, row_labels = xlabs, col_labels = ylabs,
        ax = ax, cmap = "YlGn", cbarlabel = "Label")

# plt.show()

Agregar anotaciones de texto a las celdas con annotate_heatmap

Por último, si quieres agregar anotaciones de texto a cada celda del mapa de calor puedes utilizar la función annotate_heatmap como se muestra en el siguiente bloque de código. Recuerda importar matplotlib para poder utilizarla.

Mapa de calor en matplotlib con leyenda y anotaciones de texto

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

# Semilla para reproducibilidad
np.random.seed(2)

# Datos
data = np.random.random((8, 8))

# Etiquetas
xlabs = ["G1", "G2", "G3", "G4",
         "G5", "G6", "G7", "G8"]
ylabs = ["A", "B", "C", "D",
         "E", "F", "G", "H"]
         
# Mapa de calor
fig, ax = plt.subplots()
im, cbar = heatmap(data, row_labels = xlabs, col_labels = ylabs,
                   ax = ax, cmap = "YlGn", cbarlabel = "Título")
texts = annotate_heatmap(im, valfmt = "{x:.1f}")

# plt.show()
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Comprar en Amazon
Data Sketches

A journey of imagination, exploration, and beautiful data visualizations

Comprar en Amazon

También te puede interesar