Created
February 11, 2014 05:39
-
-
Save tonysyu/8929788 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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