¿Cómo puedo establecer colores de fondo personalizados de los campos de un mapa de calor de seaborn? (facecolors de matplotlib collections.QuadMesh, Python)
Quiero establecer el color de fondo de algunos campos de un mapa de calor de seaborn DESPUÉS de que se haya creado (personalizando algunos colores en función de su posición).
Puedo acceder a los valores de “facecolor” a través del objeto “collections.QuadMesh” de matplotlib. Cuando modifico los valores (he probado diferentes formas), los cambios se reflejan, pero los colores de fondo que se muestran al mostrar o exportar el gráfico no cambian.
¿Qué me falta aquí?
Este es un ejemplo (no) funcional:
import numpy as np
import numpy.testing
import pandas as pd
import seaborn as sns
from matplotlib.collections import QuadMesh
import matplotlib.pyplot as plt
CUSTOM_BACKGROUND = np.array([0.35, 0.8, 0.55, 1.0])
df = pd.DataFrame(data={'col1': [1, 1], 'col2': [2,2]})
matrix_size = df.shape[0]
ax = sns.heatmap(df)
quadmesh = ax.findobj(QuadMesh)[0]
facecolors_old = quadmesh.get_facecolors()
facecolors_new = facecolors_old.copy()
facecolors_new[1] = CUSTOM_BACKGROUND
<h1>No funciona:</h1>
quadmesh.set_facecolors(facecolors_new)
quadmesh.original_facecolor = facecolors_new
facecolors_old[1] = CUSTOM_BACKGROUND
quadmesh.facecolors[1] = CUSTOM_BACKGROUND
funciona:
quadmesh.set_facecolors('none')
pruebas pasadas:
facecolors_actual = quadmesh.get_facecolors()
numpy.testing.assert_array_equal(facecolors_new, facecolors_actual)
facecolors_actual = quadmesh.facecolors
numpy.testing.assert_array_equal(facecolors_new, facecolors_actual)
NOTA: sin embargo, al inspeccionar "quadmesh._facecolors" se muestran los valores antiguos!
muestra los colores antiguos
plt.show()
Versiones de las dependencias:
[tool.poetry.dependencies]
python = "^3.8"
pandas = "^1.2"
seaborn = "^0.11.2"
Observación:
Este enfoque solía funcionar para mí antes de actualizar las dependencias. He adaptado parte del código de aquí para dibujar matrices de confusión personalizadas utilizando el mismo enfoque: pretty-print-confusion-matrix
davy.ai
Parece que los cambios realizados en los colores de fondo del objeto QuadMesh no se están reflejando en la salida porque la función
sns.heatmap()
crea una copia de los datos antes de trazarlos. Por lo tanto, modificar el objeto QuadMesh después de haber sido trazado no tiene efecto en los datos originales utilizados para crear el mapa de calor.Una forma de lograr el resultado deseado es crear un nuevo DataFrame con los valores modificados y trazar un nuevo mapa de calor con la misma configuración que el original, excepto por los colores de fondo modificados. Por ejemplo:
Aquí, creamos un nuevo DataFrame
df_mod
con los mismos valores quedf
, pero modificamos el valor en la posición(1,1)
para tener un color de fondo personalizado. Luego, utilizamos la misma configuración que el mapa de calor original para crear un nuevo mapa de calorax_mod
, pero con el color de fondo modificado. También utilizamos el parámetromask
para ocultar la celda modificada, ya que ahora contiene un valorNaN
.Finalmente, obtenemos el objeto
QuadMesh
del nuevo mapa de calor y modificamos su color de fondo para reflejar el color de fondo personalizado. Luego podemos mostrar el mapa de calor modificado usandoplt.show()
.