0
import brewer2mpl
import numpy as np

a = np.random.rand(3) # a[0] represents value of rect1, a[1] of rect[2]....

def get_colors():    
    """
    Get colorbrewer colors, which are nicer
    """            
    bmap   = brewer2mpl.get_map('Accent','qualitative',6)
    return bmap.mpl_colors

rect1 = matplotlib.patches.Rectangle((2,2), 1, 1, color='yellow'))
ax.add_patch(rect1)
rect2 = matplotlib.patches.Rectangle((3,3), 1, 1, color='green'))
ax.add_patch(rect2)
rect3 = matplotlib.patches.Rectangle((5,5), 1, 1, color='red'))
ax.add_patch(rect3)

I would like the color of the rectangle to vary based on the value of the vector 'a'. Instead of pure yellow/green/red color, select a color from a range, preferably the brewer2mpl colors

3 Answers 3

1

From what I can read, mpl_color is a list of colors. The colors are 3-tuples, with a range in (0,1) representing the rgb amount. You can set a color to be such a triple.

import pylab as py

py.plot([0,1],[2,3], color = (1,0,0.))
py.savefig('tmp.png')

enter image description here

So all you have to do is take the entry in the vector a (I'll call it avalue below, with 0<avalue<1) and map it to an appropriate integer. For example

colorlist = get_colors()
colorlength = len(colorlist)
py.plot([0,1],[2,3], color = colorlist[int(avalue*colorlength)])
Sign up to request clarification or add additional context in comments.

Comments

1

You don't necessarily need to create a np array to hold random indices to the colors you want to use.

In order to assign a color to each rect, you can easily cycle through the colors using itertools:

import brewer2mpl
import numpy as np
import itertools

color_map = brewer2mpl.get_map('Accent', 'qualitative', 6)
colors = itertools.cycle(color_map.mpl_colors)

rect1 = matplotlib.patches.Rectangle((2,2), 1, 1, color=next(colors))

That would assign the colors following the original sequence. If you want to randomize the colors, you can do so easily:

import random
import itertools

color_map = brewer2mpl.get_map('Accent', 'qualitative', 6)
colors = [c for c in color_map.mpl_colors]
random.shuffle(colors)
rnd_colors = itertools.cycle(colors)

rect1 = matplotlib.patches.Rectangle((2,2), 1, 1, color=next(rnd_colors))

If you're sure you have enough colors for your rects, you don't really need to cycle and can just pop some randomly:

color_map = brewer2mpl.get_map('Accent', 'qualitative', 6)
colors = [c for c in color_map.mpl_colors]
random.shuffle(colors)

rect1 = matplotlib.patches.Rectangle((2,2), 1, 1, color=colors.pop())

3 Comments

random.choice(sequence) is another great way to get a random selection, but you don't want to use it here since you could possibly get repeated colors!
thanks, but I want to assign colors based on a range. so instead of random assignment, lower values should get different colors from higher values...
You mean different values should be grouped into the same color, so values 0 - 25 would be red, 26 - 50 blue, etc.? Check Joel's answer, you can directly access and assign the color tuple from mpl_colors —you'll just have to figure out the index that corresponds to each range.
1

Not sure if colorbrewer or the use of a was more important and they don't seem well-suited to use at the same time. Several approaches:

import brewer2mpl
import numpy as np
import matplotlib


bigness = 8
a = np.random.rand(bigness) # a[0] represents value of rect1, a[1] of rect[2]....

def get_colors(numpatches):
    """
    Get colorbrewer colors, which are nicer
    """
    bmap   = brewer2mpl.get_map('Accent','qualitative', numpatches)
    return bmap.mpl_colors


fig, axs = matplotlib.pyplot.subplots(ncols=3, nrows=1)
colors = get_colors(bigness)

for i in (0,2,3,5,bigness-1):
    rect = matplotlib.patches.Rectangle((i,i), 1, 1, color=colors[i])
    axs[0].add_patch(rect)
axs[0].set_title('Color evenly spaced\nfrom colorbrewer')

patches = []
for i in (0,2,3,5,bigness-1):
    rect = matplotlib.patches.Rectangle((i,i), 1, 1)
    patches.append(rect)
collection = matplotlib.collections.PatchCollection(patches,
                                                    cmap=matplotlib.cm.hot)
collection.set_array(a)
collection.set_edgecolor('none')
axs[1].add_collection(collection) # and why not?
axs[1].set_title('Color from\nrandom array a')


patches = []
for i in a:
    loc = i*bigness
    rect = matplotlib.patches.Rectangle((loc,loc), 1, 1)
    patches.append(rect)
collection = matplotlib.collections.PatchCollection(patches,
                                                    cmap=matplotlib.cm.hot)
collection.set_array(a)
collection.set_edgecolor('none')
axs[2].add_collection(collection) # and why not?


axs[2].set_title('Color matches location\nboth from a')

for ax in axs:
    ax.set_xlim((0,bigness))
    ax.set_ylim((0,bigness))

from os.path import realpath, basename
s = basename(realpath(__file__))
fig = matplotlib.pyplot.gcf()
fig.savefig(s.split('.')[0])

matplotlib.pyplot.show()

enter image description here

1 Comment

the third option makes "to assign colors based on a range. so instead of random assignment, lower values should get different colors from higher values" explicit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.