Search code examples
pythonmatplotlibnancolormapimshow

How can I plot NaN values as a special color with imshow?


I am trying to use imshow in matplotlib to plot data as a heatmap, but some of the values are NaNs. I'd like the NaNs to be rendered as a special color not found in the colormap.

example:

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

The resultant image is unexpectedly all blue (the lowest color in the jet colormap). However, if I do the plotting like this:

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

--then I get something better, but the NaN values are drawn the same color as vmin... Is there a graceful way that I can set NaNs to be drawn with a special color (eg: gray or transparent)?


Solution

  • With newer versions of Matplotlib, it is not necessary to use a masked array anymore.

    For example, let’s generate an array where every 7th value is a NaN:

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

    .cm.get_cmap() is replaced by .colormaps.get_cmap('viridis') in matplotlib v3.7.0

    Set the color with .set_bad.

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import numpy as np
    
    arr = np.arange(100, dtype=float).reshape(10, 10)
    arr[~(arr % 7).astype(bool)] = np.nan
    
    cmap = mpl.colormaps.get_cmap('viridis')  # viridis is the default colormap for imshow
    cmap.set_bad(color='red')
    
    plt.imshow(arr, cmap=cmap)
    

    plot result


    .cm.get_cmap() is deprecated

    We can modify the current colormap and plot the array with the following lines:

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