def __call__(self, data, kind='rgb', as_string=False, vmin=None, vmax=None): """Convert a subset of colors to a given type. Parameters ---------- data : array, shape (n_colors,) Must be an array of floats between 0 and 1. These will be used to index into self.cmap. kind : 'rgb' | 'husl' | 'html' Whether to return output colors in rgb or husl space. If 'html', the color output of the call will be displayed. as_string : bool If True, return colors as plotly-style strings. Returns ------- arr : np.array | list of strings The colors associated with values in `frac`. """ data = np.atleast_1d(data) if data.ndim > 1: raise ValueError('frac must be 1-d') if vmin is not None or vmax is not None: # If we need to scale out data frac = np.clip((data - vmin) / float(vmax - vmin), 0, 1) else: frac = data if not ((frac >= 0.) * (frac <= 1.)).all(0): raise ValueError('input must be between 0 and 1, you' ' provided {}'.format(frac)) arr = self.cmap(frac) if kind == 'rgb': if as_string is False: pass else: arr = [tuple(i) for i in arr[:, :-1] * 255] arr = cl.to_rgb(arr) elif kind == 'husl': if as_string is False: arr = np.array([pl.husl.rgb_to_husl(r, g, b) for r, g, b, _ in arr]) else: arr = [tuple(i) for i in arr[:, :-1] * 255] arr = cl.to_hsl(arr) elif kind == 'html': arr = [tuple(i) for i in arr[:, :-1] * 255] arr = cl.to_hsl(arr) arr = HTML(cl.to_html(arr)) else: raise ValueError("Kind {} not supported".format(kind)) return arr
def to_strings(self, n_bins=255, kind='rgb'): """Convert colormap to plotly-style strings. Parameters ---------- n_bins : int The number of bins in the output array kind : 'rgb' | 'husl' | 'hex' | 'name' Whether to return colors in rgb, husl, or hex format. Or, return the common name for that color if possible. Returns ------- colors_string : list of strings A list of "rgb()" or "hsl()" strings suitable for use in plotly. Or a list of hex strings for online plotting. Or a list of names associated with the colors. """ # Remove the alpha array = self.cmap(np.linspace(0, 1, n_bins))[:, :-1] if kind == 'hex': colors_string = [pl.husl.rgb_to_hex(ii) for ii in array] elif kind == 'name': colors_string = _get_color_names(array * 255.) else: array = array * 255. list_of_tups = [tuple(i) for i in array] if kind == 'rgb': colors_string = cl.to_rgb(list_of_tups) elif kind == 'husl': colors_string = cl.to_hsl(list_of_tups) return colors_string
def test_to_hsl(self): scales = cl.to_hsl(cl.scales['3']['div']['RdYlBu']) self.assertEqual( scales, ['hsl(19, 96%, 67%)', 'hsl(60, 100%, 87%)', 'hsl(203, 51%, 71%)'] )
def test_to_hsl(self): scales = cl.to_hsl(cl.scales['3']['div']['RdYlBu']) self.assertEqual( scales, ['hsl(19.0, 96.0%, 67.0%)', 'hsl(60.0, 100.0%, 87.0%)', 'hsl(203.0, 51.0%, 71.0%)'] )
def interp(scl, r): ''' Replacement for colorlover.interp Interpolate a color scale "scl" to a new one with length "r" Fun usage in IPython notebook: HTML( to_html( to_hsl( interp( cl.scales['11']['qual']['Paired'], 5000 ) ) ) ) ''' c = [] SCL_FI = len(scl) - 1 # final index of color scale # garyfeng: # the following line is buggy. # r = [x * 0.1 for x in range(r)] if isinstance( r, int ) else r r = [x * 1.0 * SCL_FI / r for x in range(r)] if isinstance(r, int) else r # end garyfeng scl = cl.to_numeric(scl) def interp3(fraction, start, end): '''Interpolate between values of 2, 3-member tuples''' def intp(f, s, e): return s + (e - s) * f return tuple([intp(fraction, start[i], end[i]) for i in range(3)]) def rgb_to_hsl(rgb): ''' Adapted from M Bostock's RGB to HSL converter in d3.js https://github.com/mbostock/d3/blob/master/src/color/rgb.js ''' r, g, b = float(rgb[0]) / 255.0,\ float(rgb[1]) / 255.0,\ float(rgb[2]) / 255.0 mx = max(r, g, b) mn = min(r, g, b) h = s = l = (mx + mn) / 2 if mx == mn: # achromatic h = 0 s = 0 if l > 0 and l < 1 else h else: d = mx - mn s = d / (mx + mn) if l < 0.5 else d / (2 - mx - mn) if mx == r: h = (g - b) / d + (6 if g < b else 0) elif mx == g: h = (b - r) / d + 2 else: h = r - g / d + 4 return (int(round(h * 60, 4)), int(round(s * 100, 4)), int(round(l * 100, 4))) for i in r: # garyfeng: c_i could be rounded up so scl[c_i+1] will go off range # c_i = int(i*math.floor(SCL_FI)/round(r[-1])) # start color index # c_i = int(math.floor(i*math.floor(SCL_FI)/round(r[-1]))) # start color index # c_i = if c_i < len(scl)-1 else hsl_o c_i = int(math.floor(i)) section_min = math.floor(i) section_max = math.ceil(i) fraction = (i - section_min) # /(section_max-section_min) hsl_o = rgb_to_hsl(scl[c_i]) # convert rgb to hls hsl_f = rgb_to_hsl(scl[c_i + 1]) # section_min = c_i*r[-1]/SCL_FI # section_max = (c_i+1)*(r[-1]/SCL_FI) # fraction = (i-section_min)/(section_max-section_min) hsl = interp3(fraction, hsl_o, hsl_f) c.append('hsl' + str(hsl)) return cl.to_hsl(c)