Come posso tracciare i valori NaN come un colore speciale con imshow in matplotlib?


85

Sto cercando di utilizzare imshow in matplotlib per tracciare i dati come mappa di calore, ma alcuni dei valori sono NaN. Vorrei che i NaN fossero renderizzati come un colore speciale non trovato nella mappa dei colori.

esempio:

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()

L'immagine risultante è inaspettatamente tutta blu (il colore più basso nella mappa dei colori a getto). Tuttavia, se eseguo la stampa in questo modo:

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

- allora ottengo qualcosa di meglio, ma i valori NaN sono disegnati dello stesso colore di vmin ... C'è un modo grazioso con cui posso impostare NaNs per essere disegnato con un colore speciale (ad esempio: grigio o trasparente)?


Alcuni anni dopo ( matplotlib.__version__=='1.2.1'), funziona senza problemi.
Frédéric Grosshans

Risposte:


47

Con le versioni più recenti di Matplotlib, non è più necessario utilizzare un array mascherato.

Ad esempio, generiamo un array in cui ogni 7 ° valore è un NaN:

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

Possiamo modificare la mappa di colori corrente e tracciare l'array con le seguenti righe:

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

risultato della trama


è possibile utilizzare 0 invece di np.nan?
yukashima huksay

2
@yukashimahuksay: sì, ma dovresti mascherare questi valori. Per esempio. arr = np.ma.array(arr, mask=(arr == 0)).
Arcturus B

Penso che la "c" in "cmap" stia già per "current", quindi non chiamerei la variabile "current_cmap"
T. Gwen

3
@TGwen: Sono abbastanza sicuro che cmap stia per colormap, che è il termine usato nel documento: matplotlib.org/api/cm_api.html#matplotlib.cm.get_cmap
Arcturus B

82

Hrm, sembra che posso usare un array mascherato per fare questo:

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)

Questo dovrebbe essere sufficiente, anche se sono ancora aperto a suggerimenti. :]


Sicuramente fa il trucco. I documenti ufficiali non mostrano altro.
Agos

6
Un punto di lato - credo che facendo questo ignorare l'impostazione predefinita matplotlib.cm.jet, così io di solito faccio una copia: import copy; cmap=copy.copy(matplotlib.cm.jet). Inoltre, se vuoi impostare i valori 0 su un colore diverso, qualcosa di simile cmap._init(); cm._lut[:,0] = (1,1,1,1)dovrebbe funzionare.
keflavich

3
C'è anche set_overe set_underper controllare la colorazione dei valori fuori intervallo. Il comportamento predefinito è quello di abbinare la parte superiore / inferiore della gamma di colori.
tacaswell

2
È masked_arrayrichiesto affatto? Se acontiene valori NaN (così sembra mask=np.isnan(a)), quindi semplicemente imshowl'array acon la mappa personalizzata cmapvisualizzerà le celle NaN con il colore richiesto (bianco). Quindi funziona per me. Ci sono eccezioni?
MaciekS

2
@MaciekS, quando si utilizza una mappa dei colori divergente, non si desidera che i nanvalori e i valori mediani vengano tracciati dello stesso colore, ad esempio il bianco.
AGS
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.