Clustering
Cluster extracted colors into meaningful groups using k-means in OKLab space. A leather swatch might yield 15 shades of brown — clustering reduces them to the 3-4 groups a designer actually cares about.
Source: 12 extracted colors
Suggested: 2 (elbow method)
Clustered into 2 groups:
#c6a18161%
#44353319%
const k = suggestK(colors); // 2
const clusters = clusterColors(colors, 2);import { clusterColors, suggestK } from "colorscope/analysis";Functions
clusterColors
Cluster colors into k groups using k-means in OKLab space.
function clusterColors(
colors: readonly QuantizedColor[],
k: number,
maxIterations?: number
): ColorCluster[]| Param | Type | Default | Description |
|---|---|---|---|
colors | readonly QuantizedColor[] | — | Colors to cluster |
k | number | — | Number of clusters |
maxIterations | number | 20 | Maximum k-means iterations |
Returns: Array of k clusters sorted by proportion descending. Uses k-means++ seeding for stable results.
const clusters = clusterColors(terrazzoPalette, 5);
clusters.forEach(c => {
console.log(`${oklabToHex(c.centroid)} — ${c.members.length} colors, ${(c.proportion * 100).toFixed(0)}%`);
});
// #8B6B4A — 5 colors, 35% (warm browns)
// #6B7B7E — 4 colors, 22% (cool grays)
// ...suggestK
Suggest optimal number of clusters using the elbow method.
function suggestK(colors: readonly QuantizedColor[], maxK?: number): number| Param | Type | Default | Description |
|---|---|---|---|
colors | readonly QuantizedColor[] | — | Colors to analyze |
maxK | number | 8 | Maximum k to test |
Returns: Suggested number of clusters (1 to maxK). Computes inertia for each k and finds the "knee" in the curve.
const k = suggestK(terrazzoPalette); // 5
const clusters = clusterColors(terrazzoPalette, k);Types
ColorCluster
interface ColorCluster {
centroid: OKLab; // Cluster center in OKLab space
members: QuantizedColor[]; // Colors assigned to this cluster
proportion: number; // Sum of member proportions
}