This defines two utility functions to illustrate the colormaps (taken from https://github.com/gammapy/gammapy/blob/master/gammapy/image/plotting.py):
import numpy as np
%matplotlib inline
def grayify_colormap(cmap, mode='hsp'):
"""
Return a grayscale version a the colormap.
The grayscale conversion of the colormap is bases on perceived luminance of
the colors. For the conversion either the `~skimage.color.rgb2gray` or a
generic method called ``hsp`` [1]_ can be used. The code is loosely based
on [2]_.
Parameters
----------
cmap : str or `~matplotlib.colors.Colormap`
Colormap name or instance.
mode : {'skimage, 'hsp'}
Grayscale conversion method. Either ``skimage`` or ``hsp``.
References
----------
.. [1] Darel Rex Finley, "HSP Color Model - Alternative to HSV (HSB) and HSL"
http://alienryderflex.com/hsp.html
.. [2] Jake VanderPlas, "How Bad Is Your Colormap?"
https://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-colormap/
"""
import matplotlib.pyplot as plt
cmap = plt.cm.get_cmap(cmap)
colors = cmap(np.arange(cmap.N))
if mode == 'skimage':
from skimage.color import rgb2gray
luminance = rgb2gray(np.array([colors]))
colors[:, :3] = luminance[0][:, np.newaxis]
elif mode == 'hsp':
RGB_weight = [0.299, 0.587, 0.114]
luminance = np.sqrt(np.dot(colors[:, :3] ** 2, RGB_weight))
colors[:, :3] = luminance[:, np.newaxis]
else:
raise ValueError('Not a valid grayscale conversion mode.')
return cmap.from_list(cmap.name + "_grayscale", colors, cmap.N)
def illustrate_colormap(cmap, **kwargs):
"""
Illustrate color distribution and perceived luminance of a colormap.
Parameters
----------
cmap : str or `~matplotlib.colors.Colormap`
Colormap name or instance.
kwargs : dicts
Keyword arguments passed to `grayify_colormap`.
"""
import matplotlib.pyplot as plt
cmap = plt.cm.get_cmap(cmap)
cmap_gray = grayify_colormap(cmap, **kwargs)
figure = plt.figure(figsize=(6, 4))
v = np.linspace(0, 1, 4 * cmap.N)
# Show colormap
show_cmap = figure.add_axes([0.1, 0.8, 0.8, 0.1])
im = np.outer(np.ones(50), v)
show_cmap.imshow(im, cmap=cmap, origin='lower')
show_cmap.set_xticklabels([])
show_cmap.set_yticklabels([])
show_cmap.set_yticks([])
show_cmap.set_title('RGB & Gray Luminance of colormap {0}'.format(cmap.name))
# Show colormap gray
show_cmap_gray = figure.add_axes([0.1, 0.72, 0.8, 0.09])
show_cmap_gray.imshow(im, cmap=cmap_gray, origin='lower')
show_cmap_gray.set_xticklabels([])
show_cmap_gray.set_yticklabels([])
show_cmap_gray.set_yticks([])
# Plot RGB profiles
plot_rgb = figure.add_axes([0.1, 0.1, 0.8, 0.6])
plot_rgb.plot(v, [cmap(_)[0] for _ in v], color='r')
plot_rgb.plot(v, [cmap(_)[1] for _ in v], color='g')
plot_rgb.plot(v, [cmap(_)[2] for _ in v], color='b')
plot_rgb.plot(v, [cmap_gray(_)[0] for _ in v], color='k', linestyle='--')
plot_rgb.set_ylabel('Luminance')
plot_rgb.set_ylim(-0.005, 1.005)
The following cell defines the colormaps as in 'saods9/saotk/colorbar/default.C' of the ds9 source code and registers them with matplotlib:
from matplotlib.cm import register_cmap, cmap_d
ds9b = {'red': lambda v : 4 * v - 1,
'green': lambda v : 4 * v - 2,
'blue': lambda v : np.select([v < 0.25, v < 0.5, v < 0.75, v <= 1],
[4 * v, -4 * v + 2, 0, 4 * v - 3])}
# Note that this definition slightly differs from ds9cool, but make more sense to me...
ds9cool = {'red': lambda v : 2 * v - 1,
'green': lambda v : 2 * v - 0.5,
'blue': lambda v : 2 * v}
ds9a = {'red': lambda v : np.interp(v, [0, 0.25, 0.5, 1],
[0, 0, 1, 1]),
'green': lambda v : np.interp(v, [0, 0.25, 0.5, 0.77, 1],
[0, 1, 0, 0, 1]),
'blue': lambda v : np.interp(v, [0, 0.125, 0.5, 0.64, 0.77, 1],
[0, 0, 1, 0.5, 0, 0])}
ds9i8 = {'red': lambda v : np.where(v < 0.5, 0, 1),
'green': lambda v : np.select([v < 1/8., v < 0.25, v < 3/8., v < 0.5,
v < 5/8., v < 0.75, v < 7/8., v <= 1],
[0, 1, 0, 1, 0, 1, 0, 1]),
'blue': lambda v : np.select([v < 1/8., v < 0.25, v < 3/8., v < 0.5,
v < 5/8., v < 0.75, v < 7/8., v <= 1],
[0, 0, 1, 1, 0, 0, 1, 1])}
ds9aips0 = {'red': lambda v : np.select([v < 1/9., v < 2/9., v < 3/9., v < 4/9., v < 5/9.,
v < 6/9., v < 7/9., v < 8/9., v <= 1],
[0.196, 0.475, 0, 0.373, 0, 0, 1, 1, 1]),
'green': lambda v : np.select([v < 1/9., v < 2/9., v < 3/9., v < 4/9., v < 5/9.,
v < 6/9., v < 7/9., v < 8/9., v <= 1],
[0.196, 0, 0, 0.655, 0.596, 0.965, 1, 0.694, 0]),
'blue': lambda v : np.select([v < 1/9., v < 2/9., v < 3/9., v < 4/9., v < 5/9.,
v < 6/9., v < 7/9., v < 8/9., v <= 1],
[0.196, 0.608, 0.785, 0.925, 0, 0, 0, 0, 0])}
ds9rainbow = {'red': lambda v : np.interp(v, [0, 0.2, 0.6, 0.8, 1], [1, 0, 0, 1, 1]),
'green': lambda v : np.interp(v, [0, 0.2, 0.4, 0.8, 1], [0, 0, 1, 1, 0]),
'blue': lambda v : np.interp(v, [0, 0.4, 0.6, 1], [1, 1, 0, 0])}
# This definition seems a bit strange...
ds9he = {'red': lambda v : np.interp(v, [0, 0.015, 0.25, 0.5, 1],
[0, 0.5, 0.5, 0.75, 1]),
'green': lambda v : np.interp(v, [0, 0.065, 0.125, 0.25, 0.5, 1],
[0, 0, 0.5, 0.75, 0.81, 1]),
'blue': lambda v : np.interp(v, [0, 0.015, 0.03, 0.065, 0.25, 1],
[0, 0.125, 0.375, 0.625, 0.25, 1])}
ds9heat = {'red': lambda v : np.interp(v, [0, 0.34, 1], [0, 1, 1]),
'green': lambda v : np.interp(v, [0, 1], [0, 1]),
'blue': lambda v : np.interp(v, [0, 0.65, 0.98, 1], [0, 0, 1, 1])}
# Set aliases, where colormap exists in matplotlib
cmap_d['ds9bb'] = cmap_d['afmhot']
cmap_d['ds9grey'] = cmap_d['gray']
# Register all other colormaps
register_cmap('ds9b', data=ds9b)
register_cmap('ds9cool', data=ds9cool)
register_cmap('ds9a', data=ds9a)
register_cmap('ds9i8', data=ds9i8)
register_cmap('ds9aips0', data=ds9aips0)
register_cmap('ds9rainbow', data=ds9rainbow)
register_cmap('ds9he', data=ds9he)
register_cmap('ds9heat', data=ds9heat)
illustrate_colormap('ds9grey')
illustrate_colormap('ds9a')
illustrate_colormap('ds9b')
illustrate_colormap('ds9bb')
illustrate_colormap('ds9he')
illustrate_colormap('ds9i8')
illustrate_colormap('ds9aips0')
illustrate_colormap('ds9heat')
illustrate_colormap('ds9cool')
illustrate_colormap('ds9rainbow')