¿Cómo agregar una cruz (X) en celdas de mapa de calor como con el lenguaje R?

Me gustaría agregar una cruz (X) en las celdas de mapa de calor (dependiendo del nivel de significación, pero la pregunta es sobre la adición de la X).

Como en lenguaje R (sig.level = XXX).

Consulte el código de Python y R utilizado y las imágenes de salida correspondientes.

Gracias por tu ayuda.

# Draw the heatmap with the mask and correct aspect ratio sns.heatmap(corr, mask=mask, cmap=cmap, center=0, vmin=-1, vmax=1, square=True, linewidths=0.5, fmt=".2f", cbar_kws={"shrink": .65, "orientation": "horizontal", "ticks":np.arange(-1, 1+1, 0.2)}, annot = True, annot_kws={"weight": 'bold', "size":15}) corrplot(cor(subset (wqw, select = c(fixed.acidity:quality,ratio.sulfur.dioxide))), # compute the p matrix p.mat = cor.mtest(subset (wqw, select = c(fixed.acidity:quality,ratio.sulfur.dioxide))), # significance level 0.01 sig.level = 0.01, # Method to display : color (could be corcle, ...) method = "color", # color palette col = colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD", "#4477AA"))(200), ) ``` 

matriz de pitón Matriz r

La solución fácil es agregar un diagtwig de dispersión con un marcador en forma de X para tachar las celdas no deseadas.

 import numpy as np; np.random.seed(42) import matplotlib.pyplot as plt data = np.random.rand(10,10) mask = np.zeros_like(data) mask[np.triu_indices_from(mask)] = True data_masked = np.ma.array(data, mask=mask) fig, ax = plt.subplots() im = ax.imshow(data_masked, cmap="YlGnBu", origin="upper") fig.colorbar(im) ax.scatter(*np.argwhere(data_masked.T < 0.4).T, marker="x", color="black", s=100) plt.show() 

introduzca la descripción de la imagen aquí

El inconveniente de esto es que el ( s ) tamaño ( s ) de las marcas es independiente del número de celdas y necesita ajustarse para diferentes tamaños de figuras.

Por lo tanto, una alternativa es dibujar algunas líneas (una X son dos líneas cruzadas) en las posiciones respectivas. Aquí creamos un crossout(points, ax=None, scale=1, **kwargs) funciones crossout(points, ax=None, scale=1, **kwargs) , donde scale es el porcentaje que las líneas tomarán de cada celda.

 import numpy as np; np.random.seed(42) import matplotlib.pyplot as plt from matplotlib.collections import LineCollection def crossout(points, ax=None, scale=1, **kwargs): ax = ax or plt.gca() l = np.array([[[1,1],[-1,-1]]])*scale/2. r = np.array([[[-1,1],[1,-1]]])*scale/2. p = np.atleast_3d(points).transpose(0,2,1) c = LineCollection(np.concatenate((l+p,r+p), axis=0), **kwargs) ax.add_collection(c) return c data = np.random.rand(10,10) mask = np.zeros_like(data) mask[np.triu_indices_from(mask)] = True data_masked = np.ma.array(data, mask=mask) fig, ax = plt.subplots() im = ax.imshow(data_masked, cmap="YlGnBu", origin="upper") fig.colorbar(im) crossout(np.argwhere(data_masked.T < 0.4), ax=ax, scale=0.8, color="black") plt.show() 

Para scale=0.8 esto se ve

introduzca la descripción de la imagen aquí

Tenga en cuenta que para un gráfico de pcolormesh o un mapa de calor de origen marino (que utiliza pcolormesh internamente), sería necesario agregar 0.5 a los datos, es decir

 np.argwhere(data_masked.T < 0.4)+0.5