Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating user-defined colormap in Python matplotlib

Here is my question.

When I want use a lot of colormap, I could use

CMAP = ["summer_r", "brg_r", "Dark2", "prism", "PuOr_r", "afmhot_r", "terrain_r", "PuBuGn_r", "RdPu", \
        "gist_ncar_r", "gist_yarg_r", "Dark2_r", "YlGnBu", "RdYlBu", "hot_r"]
## value was a 3-d array, the first dimension represent the amount of 2-d array with the value (0, 1).     
## I just plot the value 1 for each value[i,:,:]
for i in range(0,len(CMAP),1):
    plt.pcolor(xx,yy,value[i,:,:], cmap = CMAP[i])      

And I can get this:

http://i8.tietuku.com/cdcdcd5f539c124b.png

But I can't clearly realize the each grid's color befor generating the figure.
Because some colormap which I add in CMAP may have the same start color. SO, some value[ i, :, :] grids will be hard to distinguish.

My idea

Using one colormap instead and split into single color for each value[ i, :, :]. So, each value grid has a different color.

For example:

## 1. cut the colormap, take "jet" for example      
cMap = plt.cm.get_cmap("jet",lut=6)      

http://i4.tietuku.com/be127c44e87a03fc.png

## 2. I havn't figured it out     
## This is the fake code 
CMAP = Func[one color -> colormap](cMap)    

Update -2016-01-18

This is my code to set different cmap and loop, but it was a bit of rigid.

cmap1 = colors.ListedColormap(["w",'red'])
cmap2 = colors.ListedColormap(["w",'blue'])
cmap3 = colors.ListedColormap(["w",'yellow'])    

CMAP = [cmap1,cmap2,cmap3] 

Then, I can cope with my original attempt.

But I was wondering is there a smart way to generate the cmap1,cmap2,......?

like image 830
Han Zhengzu Avatar asked Dec 04 '25 15:12

Han Zhengzu


1 Answers

The hard part of this is coming up with N distinctive colors. In practice, it's usually easiest to just grab random colors as long as N is small. If you'd prefer a bit nicer way of getting N distinct colors, have a look at how seaborn's husl_palette and hsl_palette are implemented. They choose N evenly spaced colors in HSL/HUSL space and convert it back to RGB.

At any rate, there are two parts to tying specific values to specific colors in matplotlib. One is the colormap and the other is the norm. The Normalize instance (the norm) handles transforming the data ranges into a 0-1 space for the colormap.

There's a function to make this use-case easier:matplotlib.colors.from_levels_and_colors. It returns a cmap and norm instance that you can pass in to imshow/pcolormesh/scatter/etc.

As a stand-alone example, let's generate data with a random number of unique integer values. We'll use random pastel colors instead of trying to do something fancy.

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

nvals = np.random.randint(2, 20)
data = np.random.randint(0, nvals, (10, 10))

colors = np.random.random((nvals, 3))
# Make the colors pastels...
colors = colors / 2.5 + 0.55

levels = np.arange(nvals + 1) - 0.5
cmap, norm = from_levels_and_colors(levels, colors)

fig, ax = plt.subplots()
im = ax.imshow(data, interpolation='nearest', cmap=cmap, norm=norm)
fig.colorbar(im, ticks=np.arange(nvals))
plt.show()

enter image description here

Not the nicest looking color palette, but it's not awful. Here's another run:

enter image description here

Even with 17 values, we're still getting fairly distinct colors by choosing random values.

like image 166
Joe Kington Avatar answered Dec 06 '25 08:12

Joe Kington