from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import math


def plot_colortable(colors, title, sort_colors=True, emptycols=0):

    cell_width = 200
    cell_height = 22
    swatch_width = 48
    margin = 12
    topmargin = 40

    ncols = 7 - emptycols
    n = ncols**3
    nrows = n // ncols + int(n % ncols > 0)

    width = cell_width * ncols + 2 * margin
    height = cell_height * nrows + margin + topmargin
    dpi = 72

    fig, ax = plt.subplots(figsize=(width / dpi, height / dpi), dpi=dpi)
    fig.subplots_adjust(margin/width, margin/height,
                        (width-margin)/width, (height-topmargin)/height)
    ax.set_xlim(0, cell_width * ncols)
    ax.set_ylim(cell_height * (nrows-0.5), -cell_height/2.)
    ax.yaxis.set_visible(False)
    ax.xaxis.set_visible(False)
    ax.set_axis_off()
    ax.set_title(title, fontsize=20, loc="left", pad=10)


    f   = 1./(ncols-1)
    mycolors = dict()
    for k in range(ncols):
        for j in range(ncols):
            for i in range(ncols):
                r = i * f
                g = j * f
                b = k * f
                rgb = "{:.3f}, {:.3f}, {:.3f}".format(r, g, b);
                argb = (r, g, b)
                h, s, v = mcolors.rgb_to_hsv(argb)
                hsv = "{:.3f}, {:.3f}, {:.3f}".format(h, s, v);
                hex = mcolors.to_hex(argb)
                ijk = "{:s}{:s}{:s}".format(str(i).zfill(2),str(j).zfill(2),str(k).zfill(2))
                mycolors[ijk] = hex

    # Sort mycolors by hue, saturation, value and name.
    if sort_colors is True:
        by_hsv = sorted((tuple(mcolors.rgb_to_hsv(mcolors.to_rgb(color))),
                         name)
                        for name, color in mycolors.items())
        names = [name for hsv, name in by_hsv]
    else:
        names = list(mycolors)

    for i, name in enumerate(names):
        row = i % nrows
        col = i // nrows
        y = row * cell_height

        swatch_start_x = cell_width * col
        text_pos_x = cell_width * col + swatch_width + 7
        hex = mycolors[name]
        r, g, b = mcolors.to_rgb(hex)
        rgb = "{:.3f}, {:.3f}, {:.3f}".format(r, g, b);
        argb = (r, g, b)
        h, s, v = mcolors.rgb_to_hsv(argb)
        hsv = "{:.3f}, {:.3f}, {:.3f}".format(h, s, v);

        ax.text(text_pos_x, y, hex, fontsize=14,
                horizontalalignment='left',
                verticalalignment='center')

        ax.add_patch(
            Rectangle(xy=(swatch_start_x, y-9), width=swatch_width,
                      height=18, facecolor=argb, edgecolor='0.7')
        )

    return fig

#plot_colortable(mcolors.BASE_COLORS, "Base Colors",
#                sort_colors=False, emptycols=1)
#plot_colortable(mcolors.TABLEAU_COLORS, "Tableau Palette",
#                sort_colors=False, emptycols=2)

plot_colortable(mcolors.CSS4_COLORS, "CSS Colors HEX Values")

# Optionally plot the XKCD colors (Caution: will produce large figure)
#xkcd_fig = plot_colortable(mcolors.XKCD_COLORS, "XKCD Colors")
#xkcd_fig.savefig("XKCD_Colors.png")

plt.savefig('rgb343_hsvsort_hex.jpg')
#plt.show()
