Source code for sid.colors

"""Copied from the utilities package from the Covid Impact Lab.

https://github.com/covid-19-impact-lab/utilities/blob/master/utilities/colors.py.""

"""
import numpy as np
import seaborn as sns
from matplotlib.colors import LinearSegmentedColormap


[docs]def get_colors(palette, number, as_cmap=False, skip_dark=0, skip_bright=0): """Return a list with hex codes representing a color palette. Args: palette (str): One of ["categorical", "ordered", "blue", "red", "yellow", "green", "orange", "purple"] or combinations of two colors, e.g. "red-green". number (int): Number of colors needed. Between 1 and 12 for non combined color scales and between 1 and 24 for combined color scales. as_cmap (bool): If True, the result is returned as matplotlib cmap. skip_dark (int): How many colors to skip from the dark side. Only available for monochrome and combined color palettes. skip_bright (int): How many colors to skip from the bright side. Only available for monochrome and combined color palettes. Returns: list or cmap: List of hex codes or cmap. """ if palette in ["categorical", "ordered"]: assert skip_bright == skip_dark == 0 if number < 0: raise ValueError("Number must be non-negative") if number == 0: res = [] elif "-" in palette: actual_number = int(number + 2 * (skip_bright + skip_dark)) if actual_number > 24: raise ValueError("Too many colors requested.") pal1, pal2 = palette.split("-") num1 = np.ceil(number / 2) num2 = np.floor(number / 2) res1 = _get_mono_colors(pal1, num1, skip_dark, skip_bright) res2 = _get_mono_colors(pal2, num2, skip_dark, skip_bright) res = res1 + res2[::-1] elif palette in ["blue", "red", "green", "yellow", "orange", "purple"]: res = _get_mono_colors(palette, number, skip_dark, skip_bright) else: if number > 12: raise ValueError("Too many colors requested.") if palette == "categorical": triangle = {i + 1: CAT_LIST[: i + 1] for i in range(12)} elif palette == "ordered": triangle = ORDERED else: raise NotImplementedError(f"{palette} is not implemented.") res = triangle[number] if as_cmap: res = LinearSegmentedColormap.from_list(palette, res) return res
[docs]def _get_mono_colors(palette, number, skip_dark, skip_bright): if number == 0: res = [] else: triangle = _mono_list_to_triangle(MONO_COLORS[palette]) actual_number = number + skip_dark + skip_bright res = triangle[actual_number][skip_dark:] # list[:-0] = [] but we need the full list in that case if skip_bright != 0: res = res[:-skip_bright] return res
[docs]def plot_colors(palette, number, skip_dark=0, skip_bright=0, size=1): """Plot a color palette. Args: palette (str): One of ["categorical", "ordered", "blue", "red", "yellow", "green", "orange", "purple"] number (int): Between 1 and 12. size (float): Scaling factor for the plot size. """ return sns.palplot( get_colors(palette, number, skip_dark=skip_dark, skip_bright=skip_bright), size=size,
)
[docs]def _mono_list_to_triangle(mono_list): indices_to_delete = [5, 6, 3, 8, 0, 11, 2, 9, 4, 7, 10] arr = np.array(mono_list) triangle = {} for i in range(12): subset = np.delete(arr.copy(), indices_to_delete[:i]).tolist() triangle[len(subset)] = subset return triangle
# ===================================================================================== # Hex codes for the basic color palettes # =====================================================================================
[docs]CAT_LIST = [ "#547482", "#C87259", "#F1B05D", "#818662", "#C2D8C2", "#6C4A4D", "#7A8C87", "#EE8445", "#C8B05C", "#3C2030", "#C89D64", "#2A3B49",
]
[docs]ORDERED = { 1: ["#547482"], 2: ["#547482", "#c87259"], 3: ["#547482", "#F1B05D", "#c87259"], 4: ["#547482", "#7A8C87", "#F1B05D", "#c87259"], 5: ["#547482", "#7A8C87", "#C2D8C2", "#F1B05D", "#c87259"], 6: ["#547482", "#7A8C87", "#C2D8C2", "#F1B05D", "#EE8445", "#c87259"], 7: ["#547482", "#7A8C87", "#C2D8C2", "#C8B05C", "#F1B05D", "#EE8445", "#c87259"], 8: [ "#547482", "#7A8C87", "#C2D8C2", "#C8B05C", "#C89D64", "#F1B05D", "#EE8445", "#c87259", ], 9: [ "#547482", "#7A8C87", "#C2D8C2", "#818662", "#C8B05C", "#C89D64", "#F1B05D", "#EE8445", "#c87259", ], 10: [ "#547482", "#7A8C87", "#C2D8C2", "#818662", "#C8B05C", "#C89D64", "#F1B05D", "#EE8445", "#c87259", "#6c4a4d", ], 11: [ "#2A3B49", "#547482", "#7A8C87", "#C2D8C2", "#818662", "#C8B05C", "#C89D64", "#F1B05D", "#EE8445", "#c87259", "#6c4a4d", ], 12: [ "#2A3B49", "#547482", "#7A8C87", "#C2D8C2", "#818662", "#C8B05C", "#C89D64", "#F1B05D", "#EE8445", "#c87259", "#6c4a4d", "#3C2030",
], }
[docs]MONO_COLORS = { "blue": [ "#547482", "#5c7f8e", "#63899a", "#6f92a2", "#7b9baa", "#87a4b1", "#93adb9", "#9fb6c1", "#abbfc8", "#b6c8d0", "#c2d1d8", "#cedae0", ], "red": [ "#a04d35", "#b3563b", "#c26246", "#c87259", "#ce826c", "#d5937f", "#dba392", "#e0b1a3", "#e5bdb1", "#eacac0", "#efd6cf", "#f4e3de", ], "yellow": [ "#d98213", "#eb8d15", "#ec9627", "#efa74b", "#f1b05d", "#f3b96f", "#f4c281", "#f6ca93", "#f7d3a5", "#f9dcb7", "#fae5c9", "#fceedb", ], "green": [ "#606449", "#6b6f51", "#767b5a", "#818662", "#8c916a", "#959a75", "#9ea280", "#a6ab8c", "#afb397", "#b8bba2", "#c1c4ae", "#c9ccb9", ], "orange": [ "#d35b13", "#ea6516", "#ec752e", "#ee8445", "#f0935c", "#f2a374", "#f4b28b", "#f6bf9f", "#f8cbb1", "#f9d7c3", "#fbe3d5", "#fdefe7", ], "purple": [ "#4e3537", "#5d4042", "#6c4a4d", "#7b5458", "#8a5f63", "#996a6e", "#a2777a", "#a98286", "#b18e91", "#b9999c", "#c1a5a8", "#c9b1b3",
], }