Skip to content

Instantly share code, notes, and snippets.

@tonysyu
Created February 11, 2014 05:39
Show Gist options
  • Save tonysyu/8929788 to your computer and use it in GitHub Desktop.
Save tonysyu/8929788 to your computer and use it in GitHub Desktop.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
RGBS = np.asarray([mcolors.hex2color(h) for h in mcolors.cnames.values()])
# Mapping from color-component name to array index
HSV_INDEX = dict(hue=0, saturation=1, value=2)
# Dividing values used to separate hues based on trial and error.
HUE_DIVS = [0, 0.017, 0.108, 0.2, 0.44, 0.56, 0.72, 0.9]
HUE_SEQUENCE = ['reds', 'oranges', 'yellows', 'greens',
'cyans', 'blues', 'violets']
NUM_COLUMNS = 3
def luminance_from_rgbs(rgbs):
return np.sum(rgbs * np.array([[0.2126, 0.7152, 0.0722]]), axis=1)
def hsvs_from_rgbs(rgbs):
rgbs = np.reshape(rgbs, (1, -1, 3))
hsvs = mcolors.rgb_to_hsv(rgbs)[0]
return np.transpose(hsvs)
rgbs_idx = np.arange(0, len(RGBS))
hues, sats, values = hsvs_from_rgbs(RGBS)
lums = luminance_from_rgbs(RGBS)
# Low saturation colors look gray
grays = (sats < 0.05)
# Initialize dictionary of colors grouped by hue (with gray as its own "hue").
color_dict = dict(grays=rgbs_idx[grays])
# Build dictionary of colors based on hue.
for n, a, b in zip(HUE_SEQUENCE, HUE_DIVS[:-1], HUE_DIVS[1:]):
color_dict[n] = rgbs_idx[(hues >= a) & (hues < b) & ~grays]
# Add reds with high "hue" values (above maximum violet hue, but below 1) to
# those with a low "hue" value. (Necessary because the hue wraps around).
reds_high = rgbs_idx[(hues >= HUE_DIVS[-1]) & ~grays]
color_dict['reds'] = np.hstack([color_dict['reds'], reds_high])
def plot_color_dict(color_dict, sort_by=None, dx=0.2):
fig, ax = plt.subplots(figsize=(7, 10))
y = 0
color_names = HUE_SEQUENCE + ['grays']
for cname in color_names:
rgbs_idx = color_dict[cname]
ax.text(0, y, cname, fontsize=12,
horizontalalignment='left', verticalalignment='center')
rgbs = sorted_colors(rgbs_idx, sort_by=sort_by)
y -= 1
plot_section(ax, rgbs, dx, y0=y)
y -= np.ceil(len(rgbs) / float(NUM_COLUMNS))
nrows = sum(1 + np.ceil(len(v) / 3.) for v in color_dict.itervalues())
ax.set_xlim(0, NUM_COLUMNS)
ax.set_ylim(-nrows, 1)
ax.set_axis_off()
fig.subplots_adjust(left=0.1, right=1, top=1, bottom=0)
fig.set_facecolor('w')
def sorted_colors(rgbs_idx, sort_by=None):
idxs = rgbs_idx[np.argsort(sort_by[rgbs_idx])]
rgbs = mcolors.cnames.keys()
return [rgbs[i] for i in idxs]
def plot_section(ax, rgbs, dx, y0=0):
for i in range(NUM_COLUMNS):
rgbs_column = rgbs[i::NUM_COLUMNS]
x0 = i
for j, cname in enumerate(rgbs_column):
y = -j + y0
plot_color_swatch(ax, cname, x0, y, dx)
def plot_color_swatch(ax, color_name, x, y, dx):
"""Plot color line and name of color"""
pad = dx * 0.2
ax.hlines(y, x, x + dx, color=color_name, linewidth=4)
ax.text(x + dx + pad, y, color_name, fontsize=10,
horizontalalignment='left', verticalalignment='center')
plot_color_dict(color_dict, sort_by=lums)
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment