user308827
user308827

Reputation: 21981

Python draw rectangle and color in range

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

Upvotes: 0

Views: 2905

Answers (3)

cphlewis
cphlewis

Reputation: 16259

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

Upvotes: 1

jminuscula
jminuscula

Reputation: 552

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())

Upvotes: 1

Joel
Joel

Reputation: 23837

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)])

Upvotes: 1

Related Questions