Showing posts with label colormaps. Show all posts
Showing posts with label colormaps. Show all posts

Monday, May 9, 2016

More colors for Matplotlib

 
The default Matplotlib color scheme is not good. While searching for something better for my thesis, I stumbled upon Bridget Riley's painting "Gather" in the RISD museum. Is uses five colors: white, black, ochre, blue, turquoise, and a rust-colored red. But, from a distance they combine to create something far more vibrant. The blue and the turquoise hues are similar, so perhaps not the best to combine in a plot, but the others form an attractive and distinct pallet:

White #f1f0e9
Black #44525c
Rust #eb7a59
Ochre #eea300
Azure #5aa0df
Turquoise #00bac9

Surprisingly, when I ran this through a color-blindness simulator , some colors become even more distinct, so it is fairly color-blind friendly. I added colors to expand the pallet, to handle gradients and plots with extra lines.

Yellow #efcd2b
Moss #77ae64
Mauve #b56ab6
Magenta #cc79a7
Violet #8d5ccd
Indigo #606ec3
Viridian #11be8d
Chartreuse #b59f1a

These are less distinct, and not all combinations are color-blind friendly. Here's a bit of Python to define and tests these colors:

from pylab import *
from matplotlib import patches

WHITE = mpl.colors.to_rgb('#f1f0e9') RUST = mpl.colors.to_rgb('#eb7a59') OCHRE = mpl.colors.to_rgb('#eea300') AZURE = mpl.colors.to_rgb('#5aa0df') TURQUOISE = mpl.colors.to_rgb('#00bac9') BLACK = mpl.colors.to_rgb('#44525c') YELLOW = mpl.colors.to_rgb('#efcd2b') INDIGO = mpl.colors.to_rgb('#606ec3') VIOLET = mpl.colors.to_rgb('#8d5ccd') MAUVE = mpl.colors.to_rgb('#b56ab6') MAGENTA = mpl.colors.to_rgb('#cc79a7') CHARTREUSE = mpl.colors.to_rgb('#b59f1a') MOSS = mpl.colors.to_rgb('#77ae64') VIRIDIAN = mpl.colors.to_rgb('#11be8d')

GATHER = [WHITE,RUST,OCHRE,AZURE,TURQUOISE,BLACK] COLORS = [BLACK,WHITE,YELLOW,OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE,INDIGO,VIOLET,MAUVE,MAGENTA,RUST] CYCLE = [BLACK,RUST,AZURE,OCHRE,TURQUOISE,MAUVE,YELLOW,INDIGO] mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=CYCLE)

def test_panel(COLORS): ax = gca() NCOLORS = len(COLORS) axis('off') xlim(0,NCOLORS) ylim(NCOLORS,0) for j in range(NCOLORS): for i in range(NCOLORS): ax.add_patch(patches.Rectangle((i,j),1,1,linewidth=1, edgecolor='none',facecolor=COLORS[i])) ax.add_patch(patches.Rectangle((i+.25,j+.25),.5,.5,linewidth=1, edgecolor='none',facecolor=COLORS[j])) axis('equal')

figure(figsize=(6,3),dpi=200) subplots_adjust(0,0,1,1,0.1,0) subplot(111) test_panel(COLORS) savefig('colorblind_test_panel.png',bbox_inches='tight',pad_inches=0) </pre></div>

Two squences form decent color maps. They aren't perceptually uniform, but pass the color blindness simulator tests. Adding violet, mauve, and moss, to the original Gather pallet creates a hue wheel. This one flunks color-blindness test (see Crameri et al. ). Here they are in python:

riley2 = matplotlib.colors.LinearSegmentedColormap.from_list('riley2',
    [INDIGO,VIOLET,MAUVE,MAGENTA,RUST,OCHRE])

riley3 = matplotlib.colors.LinearSegmentedColormap.from_list('riley3', [OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE])

# Smoothed out mauve, violet, rust, ochre, moss, turquoise, azure, in a loop hues = ['#8c62cc', '#9560c8', '#9e62c3', '#a765be', '#b068b6', '#bb6caa', '#c66f98', '#d27384', '#dd7670', '#e67c5c', '#ea8348', '#ec8b34', '#ec9421', '#e99c13', '#dea212', '#c9a620', '#b0a934', '#96ab4a', '#7cae60', '#62b076', '#48b38c', '#2eb5a2', '#1ab7b6', '#12b6c5', '#1cb2ce', '#2dadd4', '#41a7d8', '#529fdb', '#6194db', '#6d86d8', '#7977d4', '#836ad0'] riley = matplotlib.colors.LinearSegmentedColormap.from_list('riley',hues)

# Make new maps behave like native Matplotlib maps plt.register_cmap(name='riley2',cmap=riley2) plt.register_cmap(name='riley3',cmap=riley3) plt.register_cmap(name='riley' ,cmap=riley )

# Show as figure figure(figsize=(5,1),dpi=300) subplot(311) imshow([linspace(0,1,256)],cmap='riley2',aspect='auto') axis('off'); tight_layout() subplot(312) imshow([linspace(0,1,256)],cmap='riley3',aspect='auto') axis('off'); tight_layout() subplot(313) imshow([linspace(0,1,256)],cmap='riley',aspect='auto') axis('off'); tight_layout() subplots_adjust(hspace=0.3) savefig('moremaps.png') </pre></div>