#!/usr/bin/env python # coding: utf-8 # # Implement ds9 colormaps in matplotlib # # This defines two utility functions to illustrate the colormaps (taken from https://github.com/gammapy/gammapy/blob/master/gammapy/image/plotting.py): # In[1]: import numpy as np get_ipython().run_line_magic('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: # In[2]: 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) # # DS9 grey # In[3]: illustrate_colormap('ds9grey') # # DS9 a # In[4]: illustrate_colormap('ds9a') # # DS9 b # In[5]: illustrate_colormap('ds9b') # # DS9 bb # In[6]: illustrate_colormap('ds9bb') # #DS9 he # In[7]: illustrate_colormap('ds9he') # # DS9 i8 # In[8]: illustrate_colormap('ds9i8') # # DS9 aips0 # In[9]: illustrate_colormap('ds9aips0') # #DS9 heat # In[10]: illustrate_colormap('ds9heat') # #DS9 cool # In[11]: illustrate_colormap('ds9cool') # #DS9 rainbow # In[12]: illustrate_colormap('ds9rainbow')