NumberOneRobot
NumberOneRobot

Reputation: 1781

How can I turn a NumPy array into a MatPlotLib colormap?

I am trying to create a color map of 4 different colors. I have a NumPy array, and there are 4 values in that array: 0, .25, .75, and 1. How can I make MatPlotLib plot, for instance, green for 0, blue for .25, yellow for .75, and red for 1?

Thanks!

Upvotes: 7

Views: 12377

Answers (4)

Arthur Magill
Arthur Magill

Reputation: 63

The answer from user2660966 set me on the right track, but you can actually make things quite a lot simpler. This is what I ended up with:

import numpy as np
from matplotlib import colors

def array2cmpa(X):
    # Assuming array is Nx3, where x3 gives RGB values
    # Append 1's for the alpha channel, to make X Nx4
    X = np.c_[X,ones(len(X))]

    return colors.LinearSegmentedColormap.from_list('my_colormap', X)

Behaviour may be a bit odd if you're trying to build a non-continuous colormap, but most maps are continuous so this has never been a problem for me.

Upvotes: 2

user2660966
user2660966

Reputation: 975

I suggest this function that converts a Nx3 numpy array into a colormap

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors

#-----------------------------------------
def array2cmap(X):
    N = X.shape[0]

    r = np.linspace(0., 1., N+1)
    r = np.sort(np.concatenate((r, r)))[1:-1]

    rd = np.concatenate([[X[i, 0], X[i, 0]] for i in xrange(N)])
    gr = np.concatenate([[X[i, 1], X[i, 1]] for i in xrange(N)])
    bl = np.concatenate([[X[i, 2], X[i, 2]] for i in xrange(N)])

    rd = tuple([(r[i], rd[i], rd[i]) for i in xrange(2 * N)])
    gr = tuple([(r[i], gr[i], gr[i]) for i in xrange(2 * N)])
    bl = tuple([(r[i], bl[i], bl[i]) for i in xrange(2 * N)])


    cdict = {'red': rd, 'green': gr, 'blue': bl}
    return colors.LinearSegmentedColormap('my_colormap', cdict, N)
#-----------------------------------------
if __name__ == "__main__":

    #define the colormar
    X = np.array([[0., 1., 0.],  #green
                  [0., 0., 1.],  #blue
                  [1., 1., 0.],  #yellow
                  [1., 0., 0.]]) #red
    mycmap = array2cmap(X)

    values = np.random.rand(10, 10)
    plt.gca().pcolormesh(values, cmap=mycmap)

    cb = plt.cm.ScalarMappable(norm=None, cmap=mycmap)
    cb.set_array(values)
    cb.set_clim((0., 1.))
    plt.gcf().colorbar(cb)
    plt.show()

will produce : enter image description here

Upvotes: 4

reptilicus
reptilicus

Reputation: 10397

There's a few different ways to do it. Here's one I've used in the past:


def color(value, data):
    c=colorsys.hsv_to_rgb(value / data.max() / (1.1), 1, 1)
return c[::-1]

If you pass an array of values, and the data point to it, it should return a color ranging from blue to red based on it rank related to the max of the array passed.

See also example code here: http://www.scipy.org/Cookbook/Matplotlib/ColormapTransformations

Upvotes: 0

ecatmur
ecatmur

Reputation: 157314

Try ListedColormap with BoundaryNorm. See http://matplotlib.sourceforge.net/examples/api/colorbar_only.html for an example.

Upvotes: 1

Related Questions