import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors


SORT_HSV = dict(h=0, s=1, v=2)
def get_colors(sort_by='h'):
    """Return named colors sorted by luminance, hue, saturation, or value"""
    hexs = mcolors.cnames.values()

    rgbs = [mcolors.hex2color(h) for h in hexs]
    if sort_by == 'luminance':
        luminance = np.sum(rgbs * np.array([[0.2126, 0.7152, 0.0722]]), axis=1)
        idxs = np.argsort(luminance)
    else:
        # rgb_to_hsv requires and returns 3d arrays (M x N x 3)
        rgbs = np.reshape(rgbs, (1, -1, 3))
        hsvs = mcolors.rgb_to_hsv(rgbs)[0]
        idxs = np.argsort(hsvs[:, SORT_HSV[sort_by]])
    colors = mcolors.cnames.keys()
    return [colors[i] for i in idxs]


def plot_column(colors, x0, dx):
    pad = dx * 0.2
    for i, c in enumerate(colors):
        ax.hlines(-i, x0, x0 + dx, color=c, linewidth=2)
        ax.text(x0 + dx + pad, -i, c, fontsize=10,
                horizontalalignment='left', verticalalignment='center')


colors = get_colors()
ncolumns = 3

fig, ax = plt.subplots(figsize=(6,10))

dx = 0.2
for i in range(ncolumns):
    color_column = colors[i::ncolumns]
    x0 = i
    plot_column(color_column, x0, dx)

height = np.ceil(len(colors) / float(ncolumns))
ax.set_xlim(0, ncolumns)
ax.set_ylim(-height - 1, 1)
ax.set_axis_off()

fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
fig.set_facecolor('w')

plt.show()

