Matplotlib Grayscale with Visually Excellent NA Fields

I am creating a heatmap that will be used in the publication. The publication is limited to black and white printing, so I create a heat map in shades of gray. The problem is that in the heatmap there are several squares that are “not applicable”, which I want to visually distinguish from other cells. My understanding is that this is possible (?) It is possible using arrays with a mask in a mask, if a heat map is colored at both ends of the scale, and masked fields can simply be displayed as white. The problem is that I would like to use the full spectrum from white to black to illustrate a range of data other than NA. Do NA cells need to be distinguished with some other visual mechanism, such as strikethrough?

Below is a minimal example of shades of gray with a mask array (adapted from here ). The NA values ​​are probably masked here, you just can't say it because it uses white, which is already used as the color at the upper end of the allowable spectrum.

import numpy as np from pylab import * z = rand(10, 25) z = np.ma.masked_array(z,mask=z>0.8) c = pcolor(z) set_cmap('gray') colorbar() c = pcolor(z, edgecolors='w', linewidths=1) axis([0,25,0,10]) savefig('plt.png') show() 

enter image description here

+4
source share
2 answers

A simple solution is to simply cut the patch of background axes. For instance:.

 import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm np.random.seed(1977) data = np.random.random((10,25)) data = np.ma.masked_greater(data, 0.8) fig, ax = plt.subplots() im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=1, antialiased=True) fig.colorbar(im) ax.patch.set(hatch='xx', edgecolor='black') plt.show() 

enter image description here

Note that if you do not want borders to be drawn between empty cells, you can use pcolor instead of pcolormesh . For example, if we change the line:

 im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=1, antialiased=True) 

in

 im = ax.pcolor(data, cmap=cm.gray, edgecolors='white', linewidths=1) 

We'll get:

enter image description here

The difference is subtle. Rows are not connected between adjacent empty cells using pcolor . What aesthetics you prefer is purely personal, but it emphasizes the key difference between pcolor and pcolormesh .

+10
source

I could not reproduce Joe's answer by adding the ax.patch.set_hatch('x') patch. Instead, I had to create a patch as a rectangle in accordance with this question as

 import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm import matplotlib.patches as patches data = np.random.random((10,25)) data = np.ma.masked_greater(data, 0.8) fig, ax = plt.subplots() im = ax.pcolormesh(data, cmap=cm.gray, edgecolors='white', linewidths=0) fig.colorbar(im) # ax.patch.set_hatch('x') replaced by: p = patches.Rectangle((0,0), 25, 10, hatch='xx', fill=None,zorder=-10) ax.add_patch(p) plt.show() 

In addition, pcolormesh now sorted, so it can be used here.

+3
source

All Articles