{ "cells": [ { "cell_type": "markdown", "id": "2ad7fc41", "metadata": {}, "source": [ "# Color Palette in FuncSketch" ] }, { "cell_type": "code", "execution_count": null, "id": "803d969c", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "import colour\n", "import colour.notation\n", "import numpy\n", "import plotly.graph_objects\n", "import IPython.display\n", "import plotly.io\n", "\n", "# cspell: ignore RRGGBB\n", "\n", "\n", "def hex_rgb_to_oklch(hex_color: str) -> numpy.ndarray:\n", " \"\"\"Convert RGB in hexadecimal format to Oklch.\n", "\n", " Args:\n", " hex_color (str): Hexadecimal color string (e.g., \"#RRGGBB\").\n", "\n", " Returns:\n", " numpy.ndarray: Oklch color representation (lightness, chroma, hue).\n", " \"\"\"\n", " return colour.convert(colour.notation.HEX_to_RGB(hex_color), \"sRGB\", \"Oklch\")\n", "\n", "\n", "def plot_color_palette(center_oklch: numpy.ndarray) -> IPython.display.HTML:\n", " \"\"\"Plot color palette.\n", "\n", " Args:\n", " center_oklch (numpy.ndarray): Center color in Oklch.\n", "\n", " Returns:\n", " IPython.display.HTML: HTML representation of the color palette plot.\n", " \"\"\"\n", " l_point = numpy.array([0.0, center_oklch[0], 1.0])\n", " c_point = numpy.array([0.0, center_oklch[1], 0.0])\n", " h_point = numpy.array([center_oklch[2]] * 3)\n", "\n", " l_interp = numpy.linspace(0.0, 1.0, 101)\n", " c_interp = numpy.interp(l_interp, l_point, c_point)\n", " h_interp = numpy.interp(l_interp, l_point, h_point)\n", "\n", " lch_interp = numpy.stack((l_interp, c_interp, h_interp), axis=1)\n", "\n", " rgb_interp = colour.convert(lch_interp, \"Oklch\", \"sRGB\")\n", "\n", " rgb_bytes = numpy.round(rgb_interp * 255).astype(int)\n", " if numpy.any(rgb_bytes < 0) or numpy.any(rgb_bytes > 255):\n", " raise ValueError(\"RGB values are out of bounds.\")\n", "\n", " rgb_in_hex = [f\"#{r:02x}{g:02x}{b:02x}\" for r, g, b in rgb_bytes]\n", "\n", " figure = plotly.graph_objects.Figure()\n", " figure.add_heatmap(\n", " z=l_interp,\n", " x=list(range(len(rgb_in_hex))),\n", " y=[0] * len(rgb_in_hex),\n", " coloraxis=\"coloraxis\",\n", " text=rgb_in_hex,\n", " showscale=False,\n", " )\n", " figure.update_layout(\n", " {\n", " \"coloraxis\": {\n", " \"colorscale\": [\n", " [pos, color] for pos, color in zip(l_interp, rgb_in_hex)\n", " ],\n", " \"cmin\": 0.0,\n", " \"cmax\": 1.0,\n", " }\n", " }\n", " )\n", "\n", " return IPython.display.HTML(\n", " plotly.io.to_html(\n", " figure,\n", " full_html=False,\n", " include_plotlyjs=\"cdn\",\n", " include_mathjax=False,\n", " )\n", " )" ] }, { "cell_type": "markdown", "id": "52c6d213", "metadata": {}, "source": [ "## Primary Color" ] }, { "cell_type": "code", "execution_count": null, "id": "7fde947d", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "PRIMARY = numpy.array([0.7, 0.14, 0.15])\n", "plot_color_palette(PRIMARY)" ] }, { "cell_type": "markdown", "id": "ae15a4d8", "metadata": {}, "source": [ "## Gray Color" ] }, { "cell_type": "code", "execution_count": null, "id": "b7b215ac", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "GRAY = numpy.array([0.7, 0.02, 0.15])\n", "plot_color_palette(GRAY)" ] }, { "cell_type": "markdown", "id": "4b1a2224", "metadata": {}, "source": [ "## Error Color" ] }, { "cell_type": "code", "execution_count": null, "id": "df6c6907", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "ERROR = hex_rgb_to_oklch(\"#CB0541\")\n", "plot_color_palette(ERROR)" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.14" } }, "nbformat": 4, "nbformat_minor": 5 }