def bivariate_matrix_from_palette(palette_name='PiYG', n_colors=3): #full_palette = sns.diverging_palette(150, 275, s=80, l=40, n=(cmap_n_colors - 1) * 2 + 1) full_palette = sns.color_palette(palette_name, n_colors=(n_colors - 1) * 2 + 1) cmap_x = full_palette[n_colors - 1:] cmap_y = list(reversed(full_palette))[n_colors - 1:] cmap_xy = [] for j in range(n_colors): for i in range(n_colors): x = spectra.rgb(*cmap_x[i][0:3]) y = spectra.rgb(*cmap_y[j][0:3]) if i == j and i == 0: cmap_xy.append(x.darken(1.5).rgb) elif i == 0: cmap_xy.append(y.rgb) elif j == 0: cmap_xy.append(x.rgb) else: blended = x.blend(y, ratio=0.5) if i == j: blended = blended.saturate(7.5 * (i + 1)) else: blended = blended.saturate(4.5 * (i + 1)) cmap_xy.append(blended.rgb) cmap_xy = np.array(cmap_xy).reshape(n_colors, n_colors, 3) return cmap_xy
def make_grid_color(bg_color, font_color, weight=0.1): bg_color = to_rgb_tuple(bg_color) font_color = to_rgb_tuple(font_color) s_bg_color = spectra.rgb(*[c / 255 for c in bg_color]) s_font_color = spectra.rgb(*[c / 255 for c in font_color]) return s_bg_color.blend(s_font_color, weight).hexcode
def get_colour(self, val, colformat="hex", lighten=0.3): """Given a value, return a colour within the colour scale""" # Ported from the original JavaScript for continuity # Seems to work better than adjusting brightness / saturation / luminosity rgb_converter = lambda x: max(0, min(1, 1 + ((x - 1) * lighten))) try: # When we have non-numeric values (e.g. Male/Female, Yes/No, chromosome names, etc), and a qualitive # scale (Set1, Set3, etc), we don't want to attempt to parse numbers, otherwise we will end up with all # values assigned with the same color. But instead we will geta has from a string to hope to assign # a unique color for each possible enumeration value. if self.name in mqc_colour_scale.qualitative_scales and isinstance( val, str): thecolour = spectra.html(self.colours[hash(val) % len(self.colours)]) thecolour = spectra.rgb( *[rgb_converter(v) for v in thecolour.rgb]) return thecolour.hexcode # When there is only 1 color in scale, spectra.scale() will crash with DevisionByZero elif len(self.colours) == 1: thecolour = spectra.html(self.colours[0]) thecolour = spectra.rgb( *[rgb_converter(v) for v in thecolour.rgb]) return thecolour.hexcode else: # Sanity checks val = re.sub("[^0-9\.-e]", "", str(val)) if val == "": val = self.minval val = float(val) val = max(val, self.minval) val = min(val, self.maxval) domain_nums = list( np.linspace(self.minval, self.maxval, len(self.colours))) my_scale = spectra.scale(self.colours).domain(domain_nums) # Lighten colours thecolour = spectra.rgb( *[rgb_converter(v) for v in my_scale(val).rgb]) return thecolour.hexcode except: # Shouldn't crash all of MultiQC just for colours return ""
def maybe_blend(base_color, overlay_color): """ Try to blend semi transparent overlay color on opaque base color. Return None if not successful """ import re try: bc = spectra.html(base_color).to("rgb") except ValueError: return None try: # If overlay color is hex code or named color, it's # opaque, return as is return spectra.html(overlay_color).hexcode except ValueError: # Otherwise, it might be rgba pass rgba_match = re.match(r"rgba\(([^,]+),([^,]+),([^,]+),([^,]+)\)", overlay_color) if rgba_match is None: return None r, g, b, a = [float(n) for n in rgba_match.groups()] overlay_rgb = spectra.rgb(r / 255, g / 255, b / 255) blended = overlay_rgb.blend(bc, 1 - a) return blended.hexcode
def get_colour(self, val, colformat='hex'): """ Given a value, return a colour within the colour scale """ try: # Sanity checks val = re.sub("[^0-9\.]", "", str(val)) if val == '': val = self.minval val = float(val) val = max(val, self.minval) val = min(val, self.maxval) domain_nums = list( np.linspace(self.minval, self.maxval, len(self.colours))) my_scale = spectra.scale(self.colours).domain(domain_nums) # Weird, I know. I ported this from the original JavaScript for continuity # Seems to work better than adjusting brightness / saturation / luminosity rgb_converter = lambda x: max(0, min(1, 1 + ((x - 1) * 0.3))) thecolour = spectra.rgb( *[rgb_converter(v) for v in my_scale(val).rgb]) return thecolour.hexcode except: # Shouldn't crash all of MultiQC just for colours return ''
def pdfcolor_to_hex(c, cs_name): if c is None: # Per PDF 1.7 spec, default is black return "#000000" if isinstance(c, (tuple, list)): c = decode_psl_list(c) else: c = decode_psl_list([ c ])[0] if type(c) is str and c[0] == "P": c = c[1:] if cs_name in (None, "DeviceGray"): # Per PDF 1.7 spec, default is DeviceGray s = spectra.rgb(c, c, c) elif cs_name == "DeviceRGB": s = spectra.rgb(*c) elif cs_name == "DeviceCMYK": s = spectra.cmyk(*c) else: raise ValueError("Cannot handle '{}' color space. Try parsing wth parse_colors=False".format(cs_name)) return s.hexcode
def rgb(server, rgb): hsv = spectra.rgb(int(rgb[0]) / 255, int(rgb[1]) / 255, int(rgb[2]) / 255).to("hsv").values result = requests.post(server + "/state", json={ "hue": hsv[0], "saturation": hsv[1], "value": hsv[2] }) if result.status_code == 200: click.secho("Success!", fg="green") click.echo("Changed color to RGB: {}. Status Code: {}".format( rgb, result.status_code)) else: click.secho("Requests Error!", blink=True, fg="red") click.echo("Status Code: {} Message: {}".format( result.status_code, result.json()["error"]))
def get_colour(self, val, colformat='hex'): """ Given a value, return a colour within the colour scale """ try: # Sanity checks val = re.sub("[^0-9\.]", "", str(val)) if val == '': val = self.minval val = float(val) val = max(val, self.minval) val = min(val, self.maxval) domain_nums = list( np.linspace(self.minval, self.maxval, len(self.colours)) ) my_scale = spectra.scale(self.colours).domain(domain_nums) # Weird, I know. I ported this from the original JavaScript for continuity # Seems to work better than adjusting brightness / saturation / luminosity rgb_converter = lambda x: max(0, min(1, 1+((x-1)*0.3))) thecolour = spectra.rgb( *[rgb_converter(v) for v in my_scale(val).rgb] ) return thecolour.hexcode except: # Shouldn't crash all of MultiQC just for colours return ''
def separate_colorway(html_colors): try: raw_colors = [ spectra.rgb(*[c / 255 for c in to_rgb_tuple(clr)]) for clr in html_colors ] except ValueError: # Unable to parse colors as hex or rgb, return as-is return html_colors test_colors = [white] + raw_colors + [black] darkenings = list(np.zeros(len(test_colors))) threshold = 36 max_shift = 16 max_step = 16 max_iterations = 4 max_step_factor = 0.9 iterations = 0 distances = np.ones((len(html_colors) + 2, len(html_colors) + 2)) * np.nan while iterations < max_iterations: for i in range(len(test_colors) - 1): c1 = test_colors[i].darken(darkenings[i]) for j in range(i + 1, len(test_colors)): c2 = test_colors[j].darken(darkenings[j]) distance = color_distance(c1, c2) distances[i, j] = distance # When comparing to black and white, # skip if at least threshold units away if distance > threshold: continue # Compute max step based on how close colors are this_step = max_step * ((100 - distance) / 100)**2 # Clamp max steps based on how close we are to max shift allowances c1_step_up = max(0, min(this_step, max_shift - darkenings[i])) c2_step_up = max(0, min(this_step, max_shift - darkenings[j])) c1_step_down = min(0, max(-this_step, -darkenings[i] - max_shift)) c2_step_down = min(0, max(-this_step, -darkenings[j] - max_shift)) # Compute best way to lighten or darken ONE of the colors (not both) distance, (delta1, delta2) = best_darkening( c1, c2, c1_step=(c1_step_down, c1_step_up), c2_step=(c2_step_down, c2_step_up), ) distances[i, j] = distance darkenings[i] += delta1 darkenings[j] += delta2 iterations += 1 max_step *= max_step_factor result = [ clr.hexcode for clr in get_darkened_colors(test_colors, darkenings)[1:-1] ] return result
async def color_props(e): params = e.pattern_match.group(1) or "" args, color = parse_arguments(params, ['format', 'extended']) reply_message = await e.get_reply_message() if not color: await e.edit("Please provide a color...", delete_in=3) return if args.get('format') == 'rgb': r, g, b = re.findall(r'[\-.0-9]+', color) parsed = spectra.rgb(r, g, b) elif args.get('format') == 'lab': l, a, b = re.findall(r'[\-.0-9]+', color) parsed = spectra.lab(l, a, b) elif args.get('format') == 'lch': l, c, h = re.findall(r'[\-.0-9]+', color) parsed = spectra.lch(l, c, h) elif args.get('format') == 'hsl': h, s, l = re.findall(r'[\-.0-9]+', color) parsed = spectra.hsl(h, s, l) elif args.get('format') == 'hsv': h, s, v = re.findall(r'[\-.0-9]+', color) parsed = spectra.hsv(h, s, v) elif args.get('format') == 'xyz': x, y, z = re.findall(r'[\-.0-9]+', color) parsed = spectra.xyz(x, y, z) elif args.get('format') == 'cmy': c, m, y = re.findall(r'[\-.0-9]+', color) parsed = spectra.cmy(c, m, y) elif args.get('format') == 'cmyk': c, m, y, k = re.findall(r'[\-.0-9]+', color) parsed = spectra.cmyk(c, m, y, k) else: parsed = spectra.html(color) rgb = [round(x * 255) for x in parsed.to('rgb').clamped_rgb] hsl = parsed.to('hsl').values hsv = parsed.to('hsv').values formats = { 'hex': parsed.hexcode, 'rgb': values__to_str(rgb), 'hsl': values__to_str(hsl), 'hsv': values__to_str(hsv) } if args.get('extended'): formats.update({ 'lab': values__to_str(parsed.to('lab').values), 'lch': values__to_str(parsed.to('lch').values), 'xyz': values__to_str(parsed.to('xyz').values), 'cmyk': values__to_str(parsed.to('cmyk').values) }) message = "" for fmt in formats.items(): message += f"**{fmt[0]}**: `{fmt[1]}` \n" swatch = make_swatch(tuple(rgb)) await e.delete() await e.client.send_file(e.chat_id, swatch, caption=message, reply_to=reply_message)
def func(x): white = spectra.rgb(1.0, 1.0, 1.0) x = x.blend(white, ratio=0.4) if color_distance(x, white) < 0.5: x = x.blend(spectra.rgb(0.5, 1.0, 0.0), ratio=0.2) return x
print(" ", end="") for i, c in colors: mj = func(c) print(f"0x{i:02x}: 0x{mj:02x};", end=" ") print() print(" }") print() colors = [] for _ in range(256): try: r, g, b, _, i = f.readline().split() except ValueError: break c = spectra.rgb(float(r) / 255., float(g) / 255., float(b) / 255.) # if c in SAFE_COLORS: colors.append((int(i), c)) for l in open("cmclient-header.nml"): print(l, end='') # print("replace recolour_palettes(10389) {") gen_palette(gen_tint(spectra.rgb(1, 0, 0), 0.6), "deep red tint") gen_palette(gen_tint(spectra.rgb(1, 0.5, 0), 0.65), "deep orange tint") gen_palette(gen_tint(spectra.rgb(0, 1, 0), 0.65), "deep green tint") gen_palette(gen_tint(spectra.rgb(0, 1, 1), 0.65), "deep cyan tint") gen_palette(gen_tint(spectra.rgb(1, 0, 0), 0.4), "red tint") gen_palette(gen_tint(spectra.rgb(1, 0.5, 0), 0.4), "orange tint") gen_palette(gen_tint(spectra.rgb(1.0, 1.0, 0), 0.4), "yellow tint") gen_palette(gen_tint(spectra.rgb(1.0, 1.0, 0.5), 0.4), "yellow white tint")