Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Colormap choice guidelines in documentation - based on talk at SciPy 2014 #3301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 29, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
now with scripts actually included!
  • Loading branch information
kthyng committed Jul 28, 2014
commit 52d585a44cf40f93bea18f25285c638f5b288b62
171 changes: 171 additions & 0 deletions 171 doc/users/plotting/colormaps/Lfunction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
'''
Recreate Josef Albers plot illustrating the Weber-Fechner law and illustrate
with the binary matplotlib colormap, too. Trying to show the difference between
adding blackness to a color at different rates.
'''

import numpy as np
import matplotlib.pyplot as plt
from skimage import io, color
import pdb
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm, colors


mpl.rcParams.update({'font.size': 20})
mpl.rcParams['font.sans-serif'] = 'Arev Sans, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Helvetica, Avant Garde, sans-serif'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.cal'] = 'cursive'
mpl.rcParams['mathtext.rm'] = 'sans'
mpl.rcParams['mathtext.tt'] = 'monospace'
mpl.rcParams['mathtext.it'] = 'sans:italic'
mpl.rcParams['mathtext.bf'] = 'sans:bold'
mpl.rcParams['mathtext.sf'] = 'sans'
mpl.rcParams['mathtext.fallback_to_cm'] = 'True'


### Red, original Albers plot

nrows = 5

# Start with red
red = np.array([np.hstack([np.ones((nrows,1)), np.zeros((nrows,2))])])

# Get basic red in LAB
lab_add = color.rgb2lab(red)
lab_geometric = lab_add.copy()

# Alter successive rows with more black
k = 1
for i in xrange(red.shape[1]):
# more blackness is closer to 0 than one, and in first column of LAB
lab_add[0,i,0] = lab_add[0,i,0] - 10*i
print i,k
if i != 0:
lab_geometric[0,i,0] = lab_geometric[0,i,0] - 10*k
k *= 2

# Change LAB back to RGB for plotting
rgb_add = red.copy() # only change red values
temp = color.lab2rgb(lab_add)
rgb_add[0,:,0] = temp[0,:,0]
rgb_geometric = red.copy() # only change red values
temp = color.lab2rgb(lab_geometric)
rgb_geometric[0,:,0] = temp[0,:,0]

fig = plt.figure()
k = 1
for i in xrange(red.shape[1]):

# LHS: additive
ax1 = fig.add_subplot(nrows,2,i*2+1, axisbg=tuple(rgb_add[0,i,:]))
print tuple(lab_add[0,i,:])#, tuple(rgb_add[0,i,:])

# RHS: multiplicative
ax2 = fig.add_subplot(nrows,2,i*2+2, axisbg=tuple(rgb_geometric[0,i,:]))
print tuple(lab_geometric[0,i,:])#, tuple(rgb_geometric[0,i,:])

# ylabels
if i!=0:
ax1.set_ylabel(str(1*i))
ax2.set_ylabel(str(k))
k *= 2

# Turn off ticks
ax1.get_xaxis().set_ticks([])
ax2.get_xaxis().set_ticks([])
ax1.get_yaxis().set_ticks([])
ax2.get_yaxis().set_ticks([])

# Turn off black edges
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.spines['bottom'].set_visible(False)
ax1.spines['left'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.spines['bottom'].set_visible(False)
ax2.spines['left'].set_visible(False)


# common ylabel
ax1.text(-0.3, 3.8, 'Additional Parts Black',
rotation=90, transform=ax1.transAxes)


fig.subplots_adjust(hspace=0.0)
plt.show()


### Albers plot with linear scale black and white

nrows = 5
ncols = 2

x = np.linspace(0.0, 1.0, 100)
cmap = 'binary'

# Get binary colormap entries for full 100 entries
rgb = cm.get_cmap(cmap)(x)[np.newaxis,:,:3]

# Sample 100-entry rgb additively and geometrically
rgb_add = np.empty((1,nrows,3))
rgb_geometric = np.empty((1,nrows,3))

k = 1
di = 8
I0 = 5
for i in xrange(nrows):
# Do more blackness via increasing indices
rgb_add[:,i,:] = rgb[:,i*di+I0,:]

if i != 0:
print i*di+I0, di*k+I0, (I0**(1./3)+i*di**(1./3))**3
rgb_geometric[:,i,:] = rgb[:,I0+di*k,:]
k *= 2
elif i==0:
print i*di+I0, I0, (I0**(1./3)+i*di**(1./3))**3
rgb_geometric[:,i,:] = rgb[:,I0,:]

lab_add = color.rgb2lab(rgb_add)
lab_geometric = color.rgb2lab(rgb_geometric)

fig = plt.figure()
k = 1
for i in xrange(nrows):

# LHS: additive
ax1 = fig.add_subplot(nrows,ncols,i*2+1, axisbg=tuple(rgb_add[0,i,:]))

# middle: multiplicative
ax2 = fig.add_subplot(nrows,ncols,i*2+2, axisbg=tuple(rgb_geometric[0,i,:]))

# ylabels
if i!=0:
ax1.set_ylabel(str(1*i))
ax2.set_ylabel(str(k))
k *= 2

# Turn off ticks
ax1.get_xaxis().set_ticks([])
ax2.get_xaxis().set_ticks([])
ax1.get_yaxis().set_ticks([])
ax2.get_yaxis().set_ticks([])

# Turn off black edges
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.spines['bottom'].set_visible(False)
ax1.spines['left'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.spines['bottom'].set_visible(False)
ax2.spines['left'].set_visible(False)

# common ylabel
ax1.text(-0.3, 4.0, 'Steps through map indices',
rotation=90, transform=ax1.transAxes)

fig.subplots_adjust(hspace=0.0)
plt.show()
81 changes: 81 additions & 0 deletions 81 doc/users/plotting/colormaps/grayscale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'''
Show what matplotlib colormaps look like in grayscale.
Uses lightness L* as a proxy for grayscale value.
'''

from skimage import io, color
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib as mpl
import pdb
from scipy.optimize import curve_fit

mpl.rcParams.update({'font.size': 14})
mpl.rcParams['font.sans-serif'] = 'Arev Sans, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Helvetica, Avant Garde, sans-serif'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.cal'] = 'cursive'
mpl.rcParams['mathtext.rm'] = 'sans'
mpl.rcParams['mathtext.tt'] = 'monospace'
mpl.rcParams['mathtext.it'] = 'sans:italic'
mpl.rcParams['mathtext.bf'] = 'sans:bold'
mpl.rcParams['mathtext.sf'] = 'sans'
mpl.rcParams['mathtext.fallback_to_cm'] = 'True'

# Have colormaps separated into categories: http://matplotlib.org/examples/color/colormaps_reference.html

cmaps = [('Sequential', ['binary', 'Blues', 'BuGn', 'BuPu', 'gist_yarg',
'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd',
'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu',
'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd']),
('Sequential2', ['afmhot', 'autumn', 'bone', 'cool', 'copper',
'gist_gray', 'gist_heat', 'gray', 'hot', 'pink',
'spring', 'summer', 'winter']),
('Diverging', ['BrBG', 'bwr', 'coolwarm', 'PiYG', 'PRGn', 'PuOr',
'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'seismic']),
('Qualitative', ['Accent', 'Dark2', 'hsv', 'Paired', 'Pastel1',
'Pastel2', 'Set1', 'Set2', 'Set3', 'spectral']),
('Miscellaneous', ['gist_earth', 'gist_ncar', 'gist_rainbow',
'gist_stern', 'jet', 'brg', 'CMRmap', 'cubehelix',
'gnuplot', 'gnuplot2', 'ocean', 'rainbow',
'terrain', 'flag', 'prism'])]

# indices to step through colormap
x = np.linspace(0.0, 1.0, 100)

nrows = max(len(cmap_list) for cmap_category, cmap_list in cmaps)
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))

def plot_color_gradients(cmap_category, cmap_list):
fig, axes = plt.subplots(nrows=nrows, ncols=2)
fig.subplots_adjust(top=0.95, bottom=0.01, left=0.2, right=0.99, wspace=0.05)
fig.suptitle(cmap_category + ' colormaps', fontsize=14, y=1.0, x=0.6)

for ax, name in zip(axes, cmap_list):

# Get rgb values for colormap
rgb = cm.get_cmap(plt.get_cmap(name))(x)[np.newaxis,:,:3]

# Get colormap in CIE LAB. We want the L here.
lab = color.rgb2lab(rgb)
L = lab[0,:,0]
L = np.float32(np.vstack((L, L, L)))

ax[0].imshow(gradient, aspect='auto', cmap=plt.get_cmap(name))
ax[1].imshow(L, aspect='auto', cmap='binary_r', vmin=0., vmax=100.)
pos = list(ax[0].get_position().bounds)
x_text = pos[0] - 0.01
y_text = pos[1] + pos[3]/2.
fig.text(x_text, y_text, name, va='center', ha='right', fontsize=10)

# Turn off *all* ticks & spines, not just the ones with colormaps.
for ax in axes:
ax[0].set_axis_off()
ax[1].set_axis_off()


for cmap_category, cmap_list in cmaps:

plot_color_gradients(cmap_category, cmap_list)

131 changes: 131 additions & 0 deletions 131 doc/users/plotting/colormaps/lightness.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
'''
For each colormap, plot the lightness parameter L* from CIELAB colorspace along the y axis vs index through the colormap. Colormaps are examined in categories as in the original matplotlib gallery of colormaps.
'''

from skimage import io, color
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib as mpl
import pdb
from scipy.optimize import curve_fit

mpl.rcParams.update({'font.size': 14})
mpl.rcParams['font.sans-serif'] = 'Arev Sans, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Helvetica, Avant Garde, sans-serif'
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.cal'] = 'cursive'
mpl.rcParams['mathtext.rm'] = 'sans'
mpl.rcParams['mathtext.tt'] = 'monospace'
mpl.rcParams['mathtext.it'] = 'sans:italic'
mpl.rcParams['mathtext.bf'] = 'sans:bold'
mpl.rcParams['mathtext.sf'] = 'sans'
mpl.rcParams['mathtext.fallback_to_cm'] = 'True'

# Have colormaps separated into categories: http://matplotlib.org/examples/color/colormaps_reference.html

cmaps = [('Sequential', ['binary', 'Blues', 'BuGn', 'BuPu', 'gist_yarg',
'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd',
'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu',
'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd']),
('Sequential2', ['afmhot', 'autumn', 'bone', 'cool', 'copper',
'gist_gray', 'gist_heat', 'gray', 'hot', 'pink',
'spring', 'summer', 'winter']),
('Diverging', ['BrBG', 'bwr', 'coolwarm', 'PiYG', 'PRGn', 'PuOr',
'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'seismic']),
('Qualitative', ['Accent', 'Dark2', 'hsv', 'Paired', 'Pastel1',
'Pastel2', 'Set1', 'Set2', 'Set3', 'spectral']),
('Miscellaneous', ['gist_earth', 'gist_ncar', 'gist_rainbow',
'gist_stern', 'jet', 'brg', 'CMRmap', 'cubehelix',
'gnuplot', 'gnuplot2', 'ocean', 'rainbow',
'terrain', 'flag', 'prism'])]

# indices to step through colormap
x = np.linspace(0.0, 1.0, 100)

# Do plot
for cmap_category, cmap_list in cmaps:

# Do subplots so that colormaps have enough space. 5 per subplot?
dsub = 5 # number of colormaps per subplot
if cmap_category == 'Diverging': # because has 13 colormaps
dsub = 6
elif cmap_category == 'Sequential2':
dsub = 7
elif cmap_category == 'Sequential':
dsub = 7
nsubplots = int(np.ceil(len(cmap_list)/float(dsub)))

fig = plt.figure(figsize=(11.5,4*nsubplots))

for i, subplot in enumerate(xrange(nsubplots)):

locs = [] # locations for text labels

ax = fig.add_subplot(nsubplots, 1, i+1)
# pdb.set_trace()

for j, cmap in enumerate(cmap_list[i*dsub:(i+1)*dsub]):

# Get rgb values for colormap
rgb = cm.get_cmap(cmap)(x)[np.newaxis,:,:3]

# Get colormap in CIE LAB. We want the L here.
lab = color.rgb2lab(rgb)

# Plot colormap L values
# Do separately for each category so each plot can be pretty
# to make scatter markers change color along plot: http://stackoverflow.com/questions/8202605/matplotlib-scatterplot-colour-as-a-function-of-a-third-variable
if cmap_category=='Sequential':
dc = 0.6 # spacing between colormaps
ax.scatter(x+j*dc, lab[0,::-1,0], c=x, cmap=cmap + '_r', s=300, linewidths=0.)
if i==2:
ax.axis([-0.1,4.1,0,100])
else:
ax.axis([-0.1,4.7,0,100])
locs.append(x[-1]+j*dc) # store locations for colormap labels

elif cmap_category=='Sequential2':
dc = 1.15
ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, s=300, linewidths=0.)
if i==0:
ax.axis([-0.1,8.1,0,100])
else:
ax.axis([-0.1,7.0,0,100])
locs.append(x[-1]+j*dc) # store locations for colormap labels

elif cmap_category=='Diverging':
dc = 1.2
ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, s=300, linewidths=0.)
if i==0:
ax.axis([-0.1,7.1,0,100])
else:
ax.axis([-0.1,6,0,100])
locs.append(x[int(x.size/2.)]+j*dc) # store locations for colormap labels

elif cmap_category=='Qualitative':
dc = 1.3
ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, s=300, linewidths=0.)
ax.axis([-0.1,6.3,0,100])
locs.append(x[int(x.size/2.)]+j*dc) # store locations for colormap labels

elif cmap_category=='Miscellaneous':
dc = 1.25
ax.scatter(x+j*dc, lab[0,:,0], c=x, cmap=cmap, s=300, linewidths=0.)
ax.axis([-0.1,6.1,0,100])
locs.append(x[int(x.size/2.)]+j*dc) # store locations for colormap labels

# Set up labels for colormaps
ax.xaxis.set_ticks_position('top')
ticker = mpl.ticker.FixedLocator(locs)
ax.xaxis.set_major_locator(ticker)
formatter = mpl.ticker.FixedFormatter(cmap_list[i*dsub:(i+1)*dsub])
ax.xaxis.set_major_formatter(formatter)
labels = ax.get_xticklabels()
for label in labels:
label.set_rotation(60)

ax.set_xlabel(cmap_category + ' colormaps', fontsize=22)
fig.text(-0.005, 0.55, 'Lightness $L^*$', fontsize=18, transform=fig.transFigure, rotation=90)

fig.tight_layout(h_pad=0.05)
plt.show
Morty Proxy This is a proxified and sanitized view of the page, visit original site.