Question

I'm looking to plot a matplotlib colormesh on top of another colormesh. The bottom plot is simply grayscale.

The one which sits on top should however draw a transparent square when the value of the passed array is 0, and a different color for each other number in the passed array. These are 2d numpy arrays.

Currently I have:

plt.pcolormesh(array1, vmin = -32, vmax = 32, cmap = plt.cm.binary)
plt.pcolormesh(array2, cmap = plt.cm.spectral)

Obviously this doesn't produce what I'm looking for, and I assume the way to do this is to generate my own colormap, I've read this guide: http://wiki.scipy.org/Cookbook/Matplotlib/ColormapTransformations but this doesn't seem to address transparency, nor how to make specific values map to specific colors.

As a short example of what I'd like, an array:

[[0, 1]
 [2, 3]]

Should produce a grid looking like:

[[transparent, red
 [green, yellow]]

How do I go about doing this? Merging the arrays together isn't an option, as the bottom dataset is a height map, and the values of this will likely always span the values of the second array (these are agent IDs).

Was it helpful?

Solution

This code should do something akin to what you require:

Edit using masked_array:

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

#See http://stackoverflow.com/questions/18926031/how-to-extract-a-subset-of-a-colormap-as-a-new-colormap-in-matplotlib
def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
    new_cmap = colors.LinearSegmentedColormap.from_list(
        'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval),
        cmap(np.linspace(minval, maxval, n)))
    return new_cmap

#truncate the colourmap
n_colours = 4
new_cmap = truncate_colormap(cm.get_cmap('spectral_r'), 0, 0.4, n=n_colours)

#discretise the colourmap
bounds = np.linspace(0,n_colors,n_colours+1)
norm = colors.BoundaryNorm(bounds, new_cmap.N)

#build array one
array1 = np.random.rand(10,10)

#build array two
array2 = np.random.randint(0,5,100).reshape(10,10)

#mask the array
array2 = ma.masked_array(array2, array2==0)

#plot it
plt.pcolormesh(array1,cmap = plt.cm.binary)
plt.pcolormesh(array2,cmap = new_cmap, norm=norm)
cbar = plt.colorbar()
plt.show()

Here is the new output using a masked array:

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top