2

The color map in matplotlib allows to mark "bad" values, i.e. NaNs, with a specific color. When we plot the color bar afterwards, this color is not included. Is there a preferred approach to have both the contiuous color bar and a discrete legend for the specific color for bad values?

Edit: Certainly, it's possible to make use of the "extend" functionality. However, this solution is not satisfactory. The function of the legend/colorbar is to clarify the meaning of colors to the user. In my opinion, this solution does not communicate that the value is a NaN.

Code example:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

data = np.random.rand(10, 10)
data[0:3, 0:3] = np.nan  # some bad values for set_bad

colMap = cm.RdBu
colMap.set_bad(color='black')

plt.figure(figsize=(10, 9))
confusion_matrix = plt.imshow(data, cmap=colMap, vmin=0, vmax=1)
plt.colorbar(confusion_matrix)
plt.show()

Which produces:

Confusion Matrix

Simon
  • 5,034
  • 6
  • 46
  • 80
  • You can do this using one of the approaches shown at https://matplotlib.org/3.1.1/tutorials/colors/colorbar_only.html#discrete-intervals-colorbar Set the color of the bad value e.g. to -999 and use the keyword `extend`. – Joe Apr 14 '20 at 15:53

2 Answers2

1

A legend element could be created and used as follows:

from matplotlib.patches import Patch

legend_elements = [Patch(facecolor=colMap(np.nan), label='Bad values')]
plt.legend(handles=legend_elements)
JohanC
  • 59,187
  • 8
  • 19
  • 45
0

You can do this using one of the approaches used for out-of-range plotting shown at https://matplotlib.org/3.1.1/tutorials/colors/colorbar_only.html#discrete-intervals-colorbar

Set the color of the bad value e.g. to -999 and use the keyword extend.

Another approach is to used masked plotting as shown here.

Another way could be to use cmap.set_bad(). An example can be found here.

Joe
  • 6,084
  • 2
  • 18
  • 41
  • 1
    You could use a custom tick label https://stackoverflow.com/questions/11244514/modify-tick-label-text – Joe Apr 14 '20 at 17:12