add sequential bounding for chroma curves

This commit is contained in:
2026-01-16 03:14:07 -08:00
parent 4a5f8cbb39
commit fcaa25e2f5
7 changed files with 64 additions and 16 deletions

1
.gitignore vendored
View File

@@ -23,3 +23,4 @@ archive/
notebooks/color_spaces_manyview.ipynb notebooks/color_spaces_manyview.ipynb
notebooks/oklch_srgb_spherical.ipynb notebooks/oklch_srgb_spherical.ipynb
notebooks/v1.4.0/ notebooks/v1.4.0/
notebooks/v1.5.1/

View File

@@ -32,7 +32,7 @@ smoothly as a function of lightness within sRGB gamut bounds.
| Chroma curves | Color trajectories | | Chroma curves | Color trajectories |
|-------------------------------------------------------|------------------------------------------| |-------------------------------------------------------|------------------------------------------|
| ![Chroma curves](images/curves/cstar-curves-v140.png) | ![Trajectories](images/trajectories.gif) | | ![Chroma curves](images/curves/cstar-curves-v151.png) | ![Trajectories](images/trajectories.gif) |
| Palette | | Palette |
|--------------------------------| |--------------------------------|
@@ -144,7 +144,7 @@ the `monobiome` CLI:
template. template.
Running these commands in sequence from the repo root should work Running these commands in sequence from the repo root should work
out-of-the-box, after having installed the CLI tool. out-of-the-box after having installed the CLI tool.
## Applications ## Applications
This repo provides palette-agnostic theme templates for `kitty`, This repo provides palette-agnostic theme templates for `kitty`,

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -121,3 +121,21 @@ for h_str, L_points_C in Lpoints_Cqbr_Hmap.items():
max(0, min(_C, l_maxC_h(_L, _h))) max(0, min(_C, l_maxC_h(_L, _h)))
for _L, _C in zip(L_points, L_points_C, strict=True) for _L, _C in zip(L_points, L_points_C, strict=True)
] ]
# strictly enforce curve bounds s.t. there are no intersections
# order is determined by the max attained chromap
max_Cstar_Horder = [
(h_str, max(Lpoints_Cstar))
for h_str, Lpoints_Cstar in Lpoints_Cstar_Hmap.items()
]
max_Cstar_Horder = sorted(max_Cstar_Horder, key=lambda t: t[1], reverse=True)
for i in range(len(max_Cstar_Horder)-1):
outer_h, _ = max_Cstar_Horder[i]
inner_h, _ = max_Cstar_Horder[i+1]
Lpoints_Cstar_Hmap[inner_h] = [
min(inner_c, Lpoints_Cstar_Hmap[outer_h][ci])
for ci, inner_c in enumerate(Lpoints_Cstar_Hmap[inner_h])
]

View File

@@ -1,7 +1,9 @@
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from coloraide import Color from coloraide import Color
from matplotlib.collections import LineCollection
from importlib.metadata import version
from monobiome.palette import compute_hlc_map from monobiome.palette import compute_hlc_map
from monobiome.constants import ( from monobiome.constants import (
h_map, h_map,
@@ -9,6 +11,7 @@ from monobiome.constants import (
L_points, L_points,
accent_h_map, accent_h_map,
monotone_h_map, monotone_h_map,
max_Cstar_Horder,
Lspace_Cmax_Hmap, Lspace_Cmax_Hmap,
Lpoints_Cstar_Hmap, Lpoints_Cstar_Hmap,
) )
@@ -74,24 +77,50 @@ def plot_hue_chroma_star() -> None:
colors = accent_h_map.keys() colors = accent_h_map.keys()
#colors = set(["red", "orange", "yellow", "green", "blue"]) #colors = set(["red", "orange", "yellow", "green", "blue"])
for h_str in Lpoints_Cstar_Hmap: for h_str, _ in max_Cstar_Horder:
Lpoints_Cstar = Lpoints_Cstar_Hmap[h_str]
if h_str not in accent_h_map or h_str not in colors: if h_str not in accent_h_map or h_str not in colors:
continue continue
ax.fill_between(
L_points,
Lpoints_Cstar_Hmap[h_str],
alpha=0.2,
color='grey',
label=h_str
)
x, y = L_points, Lpoints_Cstar_Hmap[h_str] _h = h_map[h_str]
n = int(0.45*len(x)) h_colors = [
ax.text(x[n], y[n]-0.01, h_str, rotation=10, va='center', ha='left') Color('oklch', [_l/100, _c, _h]).convert("srgb")
for _l, _c in zip(L_points, Lpoints_Cstar, strict=True)
]
# # ax.fill_between(
# ax.scatter(
# L_points,
# Lpoints_Cstar,
# alpha=0.7,
# c=h_colors,
# #alpha=0.2,
# #color='grey',
# label=h_str
# )
# x, y = L_points, Lpoints_Cstar_Hmap[h_str]
# n = int(0.45*len(x))
# ax.text(x[n], y[n]-0.01, h_str, rotation=10, va='center', ha='left')
x = np.asarray(L_points)
y = np.asarray(Lpoints_Cstar)
pts = np.column_stack([x, y]).reshape(-1, 1, 2)
segs = np.concatenate([pts[:-1], pts[1:]], axis=1)
rgb = np.asarray(h_colors)
seg_colors = (rgb[:-1] + rgb[1:]) / 2
lc = LineCollection(segs, colors=seg_colors, linewidth=3,
capstyle="round", joinstyle="round",
label=h_str)
ax.add_collection(lc)
ax.autoscale_view()
ax.set_xlabel("Lightness (%)") ax.set_xlabel("Lightness (%)")
ax.set_xticks([L_points[0], 45, 50, 55, 60, 65, 70, L_points[-1]]) ax.set_xticks([L_points[0], 45, 50, 55, 60, 65, 70, L_points[-1]])
plt.suptitle("$C^*$ curves (v1.4.0)")
mb_version = version("monobiome")
plt.suptitle(f"$C^*$ curves (v{mb_version})")
fig.show() fig.show()

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "monobiome" name = "monobiome"
version = "1.5.0" version = "1.5.1"
description = "Monobiome color palette" description = "Monobiome color palette"
requires-python = ">=3.12" requires-python = ">=3.12"
authors = [ authors = [

2
uv.lock generated
View File

@@ -882,7 +882,7 @@ wheels = [
[[package]] [[package]]
name = "monobiome" name = "monobiome"
version = "1.5.0" version = "1.5.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "coloraide" }, { name = "coloraide" },