def register_brewer(cname='all', reverse=False, grey=False, gray=False): '''Register colourmap(s) with Matplotlib Ex.: register_brewer('ygn3') ''' from matplotlib.colors import ListedColormap from matplotlib.cm import register_cmap from jams.color import rgb2rgb01 if cname.lower() == 'all': cmaps = all_maps elif cname.lower() == 'sequential': cmaps = brewer_sequential elif cname.lower() == 'diverging': cmaps = brewer_diverging elif cname.lower() == 'qualitative': cmaps = brewer_qualitative elif cname.lower() == 'osu': cmaps = oregon elif cname.lower() == 'ncl_large': cmaps = ncl_large elif cname.lower() == 'ncl_small': cmaps = ncl_small elif cname.lower() == 'ncl_meteo_swiss': cmaps = ncl_meteo_swiss elif cname.lower() == 'mma' or cname.lower() == 'mathematica': cmaps = mathematica else: cmaps = [cname] cmaps = [capitalise(cc) for cc in cmaps] for i in cmaps: cpool = all_maps[i][:] if i in all255_maps: cpool = [rgb2rgb01(*j) for j in cpool] if reverse: cpool = cpool[::-1] if grey or gray: for j in range(len(cpool)): isgray = 0.2125 * cpool[j][0] + 0.7154 * cpool[j][ 1] + 0.072 * cpool[j][2] cpool[j] = (isgray, isgray, isgray) cmap = ListedColormap(cpool, i) register_cmap(cmap=cmap)
def bezier(icolors, ncol=255, correctlightness=True, reverse=False, cmap=None, lch=False): """ interpolates between a set of colors using a bezier spline """ # Bezier interpolation functions int2 = lambda c0, c1, t: (1. - t) * c0 + t * c1 int3 = lambda c0, c1, c2, t: (1. - t) * (1. - t) * c0 + 2. * ( 1. - t) * t * c1 + t * t * c2 int4 = lambda c0, c1, c2, c3, t: (1. - t) * (1. - t) * ( 1. - t) * c0 + 3. * (1. - t) * (1. - t) * t * c1 + 3. * ( 1. - t) * t * t * c2 + t * t * t * c3 # Check assert ncol > 1, 'Number of interpolated colours must be > 1' # Convert colours to L*a*b if lch: colors = [rgb2lch(*col2rgb(i)) for i in icolors] # in lab else: colors = [rgb2lab(*col2rgb(i)) for i in icolors] # in lab # Check - 2 icol = len(colors) if (icol > 5): raise ValueError('number of input colors > 5 not supported.') # Check sequential or diverging colours, i.e. check for increasing/decreasing lightness if (icol > 1): lights = np.array([i[0] for i in colors]) dlight = np.diff(lights) if np.all(dlight < 0.) or np.all(dlight >= 0.): idiverge = False # if icol > 4: # raise ValueError('only diverging colours supported in case of 5 input colours.') else: idiverge = True if icol == 4: print('ll', lights) raise ValueError( 'colours must have increasing or decreasing lightness in case of even number of colors: ' + ',' + ','.join([str(i) for i in lights])) # Interpolate colours if icol == 1: lab = [colors[0] for i in range(ncol)] elif icol == 2: lab0 = colors[0] lab1 = colors[1] # linear interpolation lab = list() for it in range(ncol): t = float(it) / float(ncol - 1) if correctlightness: t = correct_lightness(int2, lab0[0], lab1[0], t) lab.append(tuple([int2(lab0[i], lab1[i], t) for i in range(3)])) elif icol == 3: if idiverge: assert ( ncol % 2 ) == 1, 'number of colors has to be odd for bezier interpolation with 3 diverging colors.' ncol2 = ncol // 2 + 1 # two separate interpolations col1 = bezier(icolors[:2], ncol2) col2 = bezier(icolors[1:], ncol2) col1.extend(col2[1:]) if lch: lab = [rgb2lch(*rgb012rgb(*i)) for i in col1] else: lab = [rgb2lab(*rgb012rgb(*i)) for i in col1] else: lab0 = colors[0] lab1 = colors[1] lab2 = colors[2] # quadratic bezier interpolation lab = list() for it in range(ncol): t = float(it) / float(ncol - 1) if correctlightness: t = correct_lightness(int3, lab0[0], lab1[0], lab2[0], t) lab.append( tuple([ int3(lab0[i], lab1[i], lab2[i], t) for i in range(3) ])) elif icol == 4: lab0 = colors[0] lab1 = colors[1] lab2 = colors[2] lab3 = colors[3] # cubic bezier interpolation lab = list() for it in range(ncol): t = float(it) / float(ncol - 1) if correctlightness: t = correct_lightness(int4, lab0[0], lab1[0], lab2[0], lab3[0], t) lab.append( tuple([ int4(lab0[i], lab1[i], lab2[i], lab3[i], t) for i in range(3) ])) elif icol == 5: assert ( ncol % 2 ) == 1, 'number of colors has to be odd for bezier interpolation with 5 colors.' ncol2 = ncol // 2 + 1 col1 = bezier(icolors[:3], ncol2) col2 = bezier(icolors[2:], ncol2) col1.extend(col2[1:]) if lch: lab = [rgb2lch(*rgb012rgb(*i)) for i in col1] else: lab = [rgb2lab(*rgb012rgb(*i)) for i in col1] else: raise ValueError('number of input colors > 5 not supported.') # Reverse colours if reverse: lab = lab[::-1] # rgb [0-1] if lch: cout = [rgb2rgb01(*lch2rgb(*i)) for i in lab] else: cout = [rgb2rgb01(*lab2rgb(*i)) for i in lab] # Register colour map with matplotlib if cmap is not None: from matplotlib.colors import ListedColormap from matplotlib.cm import register_cmap iscmap = ListedColormap(cout, name=cmap, N=ncol) register_cmap(name=cmap, cmap=iscmap) return cout
def get_brewer(cname=None, names=False, rgb=False, rgb256=False, reverse=False, grey=False, gray=False): """ Get colour map either as registered handle or as RGB values (0-255 or 0-1). Examples -------- >>> import numpy as np >>> from jams.autostring import astr >>> cc = get_brewer('blues4',rgb=True) >>> print(astr(np.array(cc[0]), 4)) ['0.9373' '0.9529' '1.0000'] >>> cc = get_brewer('Blues4',rgb256=True) >>> print(cc[0]) (239, 243, 255) >>> cc = get_brewer('bLuEs4',rgb256=True,reverse=True) >>> print(cc[-1]) (239, 243, 255) >>> print(cc[0]) (33, 113, 181) >>> cc = get_brewer('blues4',rgb256=True,grey=True) >>> print(astr(np.array(cc[0]), 4)) ['242.9897' '242.9897' '242.9897'] """ from jams.color import rgb2rgb01, rgb012rgb if names: if names.lower() == 'sequential': return list(brewer_sequential.keys()) elif names.lower() == 'diverging': return list(brewer_diverging.keys()) elif names.lower() == 'qualitative': return list(brewer_qualitative.keys()) elif names.lower() == 'osu': return list(oregon.keys()) elif names.lower() == 'ncl_large': return list(ncl_large.keys()) elif names.lower() == 'ncl_small': return list(ncl_small.keys()) elif names.lower() == 'ncl_meteo_swiss': return list(ncl_meteo_swiss.keys()) elif names.lower() == 'mma' or names.lower() == 'mathematica': return list(mathematica.keys()) else: cmaps = list(all_maps.keys()) return cmaps else: cname = capitalise(cname) cpool = all_maps[cname][:] if (not rgb) and (not rgb256): # register colour map with matplotlib from matplotlib.cm import get_cmap register_brewer(cname, reverse=reverse, grey=grey, gray=gray) return get_cmap(cname) elif rgb: # tuple 0-1 if cname in all255_maps: cpool = [rgb2rgb01(*i) for i in cpool] elif rgb256: # tuple 0-255 if cname not in all255_maps: cpool = [rgb012rgb(*i) for i in cpool] if reverse: cpool = cpool[::-1] if grey or gray: for j in range(len(cpool)): isgray = 0.2125 * cpool[j][0] + 0.7154 * cpool[j][ 1] + 0.072 * cpool[j][2] cpool[j] = (isgray, isgray, isgray) return cpool