¿Cómo puedo trazar valores NaN como un color especial con imshow en matplotlib?


Estoy tratando de usar imshow en matplotlib para trazar datos como un mapa de calor, pero algunos de los valores son NAN. Me gustaría que los NaNs se representaran como un color especial que no se encuentra en el mapa de colores.

Ejemplo:

import numpy as np
import matplotlib.pyplot as plt
f = plt.figure()
ax = f.add_subplot(111)
a = np.arange(25).reshape((5,5)).astype(float)
a[3,:] = np.nan
ax.imshow(a, interpolation='nearest')
f.canvas.draw()

La imagen resultante es inesperadamente toda azul (el color más bajo en el mapa de colores de jet). Sin embargo, si hago el trazado como este:

ax.imshow(a, interpolation='nearest', vmin=0, vmax=24)

Get entonces obtengo algo mejor, pero los valores NaN se dibujan del mismo color que vmin... ¿Hay una manera elegante que puedo establecer NaNs para ser dibujado con un color especial (por ejemplo: gris o transparente)?

Author: Adam Fraser, 2010-04-05

3 answers

Hrm, parece que puedo usar una matriz enmascarada para hacer esto:

masked_array = np.ma.array (a, mask=np.isnan(a))
cmap = matplotlib.cm.jet
cmap.set_bad('white',1.)
ax.imshow(masked_array, interpolation='nearest', cmap=cmap)

Esto debería ser suficiente, aunque todavía estoy abierto a sugerencias. :]

 66
Author: Adam Fraser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-02 14:30:23

Con las versiones más recientes de Matplotlib, ya no es necesario usar una matriz enmascarada.

Por ejemplo, vamos a generar una matriz donde cada 7º valor es una NaN:

arr = np.arange(100, dtype=float).reshape(10, 10)
arr[~(arr % 7).astype(bool)] = np.nan

Podemos modificar el mapa de colores actual y trazar el array con las siguientes líneas:

current_cmap = matplotlib.cm.get_cmap()
current_cmap.set_bad(color='red')
plt.imshow(arr)

resultado de la gráfica

 13
Author: Arcturus B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-09 14:40:32

No funcionó para mí. Estaba recibiendo un mensaje de error, también lo hizo workaround:

a[3,:] = -999
masked_array=np.ma.masked_where(a==-999, a)
cmap = matplotlib.cm.jet
cmap.set_bad('w',1.)
ax.imshow(masked_array, interpolation='nearest', cmap=cmap)
 4
Author: Sergey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-07 12:01:36