1

I'm trying to plot a 2D slice of a 3D figure with matplotlib PolyCollection, but I want to set a different color for each cell. Is there a way to easily create a colormap to accomplish this?

I have a set of vertices I'm plotting then using the array argument to put an 2D array inside these vertices. I also have a 2D list that holds the RGB value for each cell. How can I generate a colormap from this 2D RGB list to pair with the PolyCollection?

For example:

import numpy
x = numpy.arange(4).reshape(2,2)
colors = [[(.2, .2, .3), (0, 0, 0)], [(.5, .5, .5), (.6, .3, .8)]]

I want the cell at (0, 0) to be (.2, .2, .3) and (0, 1) to be (0, 0, 0).

I'm guessing I need some combination of a Normalize instance and a ListedColormap.

Alternatively, is there a way to just pass an array of RGB values to PolyCollection as the array argument so that each 'value' is simply the color of the cell?

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
durden2.0
  • 9,222
  • 9
  • 44
  • 57

1 Answers1

4

If you have a sequence of 2D colors, you can use the facecolors kwarg (or equivalently collection.set_facecolors(rgb_seq).

However, if you've made the PolyCollection through ax.pcolor or otherwise called collection.set_array(some_data) in another way, you'll need to disable the scalar-color-mapping behavior by calling collection.set_array(None).

As an example:

import numpy as np
import matplotlib.pyplot as plt

rgb = np.random.random((100, 3))

fig, ax = plt.subplots()
coll = ax.pcolor(np.zeros((10, 10)))

# If we left out the "array=None", the colors would still be controlled by the
# values of the array we passed in, and the "facecolors" kwarg would be
# ignored. This is equivalent to calling `coll.set_array(None)` and then
# `coll.set_facecolors(rgb)`.
coll.set(array=None, facecolors=rgb)

plt.show()

enter image description here

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • Ah ha! That explains it. I didn't know `collection.set_array(None)` would turn off the scalar color mapping! I ended up getting a clunky version working, but this is much better. My previous version created a 1D array of indexes and a `ListedColormap` with all the colors. Then, I 'plotted' the 1D array of indexes with that colormap. You're solution is WAY less work! – durden2.0 Mar 12 '15 at 20:16
  • @durden2.0 - You're not the first person to be tripped up by the scalar color mapping vs facecolors difference. It's a moderately common gotcha that manifests in a few different ways. Glad to help, regardless! – Joe Kington Mar 13 '15 at 12:20