Note
Go to the end to download the full example code.
Voronoi Dreams¶
A Voronoi tessellation built from clustered seed points, with each cell
recoloured using dm.oklch so that hue rotates with angular position
and lightness modulates per cell. Boundary points keep the outer cells
finite for clean polygon clipping.
Demonstrates how to mix scipy.spatial.Voronoi with dartwork-mpl’s
OKLCH colour primitives for generative art.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Polygon
from scipy.spatial import Voronoi
import dartwork_mpl as dm
np.random.seed(42)
dm.style.use("scientific")
fig, ax = plt.subplots(figsize=dm.figsize("16cm", "square"))
n_clusters = 5
n_points_per_cluster = 8
points = []
for _ in range(n_clusters):
center_x = np.random.uniform(-8, 8)
center_y = np.random.uniform(-8, 8)
cluster_points = np.random.randn(n_points_per_cluster, 2) * 1.5 + [
center_x,
center_y,
]
points.extend(cluster_points)
points = np.array(points)
boundary_points = []
for x in np.linspace(-10, 10, 10):
boundary_points.append([x, -10])
boundary_points.append([x, 10])
for y in np.linspace(-10, 10, 10):
boundary_points.append([-10, y])
boundary_points.append([10, y])
all_points = np.vstack([points, boundary_points])
vor = Voronoi(all_points)
for i, region in enumerate(vor.regions):
if not region or -1 in region:
continue
polygon = [vor.vertices[j] for j in region]
if len(polygon) <= 2:
continue
polygon_array = np.array(polygon)
if (
polygon_array[:, 0].min() < -10
or polygon_array[:, 0].max() > 10
or polygon_array[:, 1].min() < -10
or polygon_array[:, 1].max() > 10
):
continue
center = polygon_array.mean(axis=0)
hue = (np.arctan2(center[1], center[0]) + np.pi) / (2 * np.pi) * 360
color = dm.oklch(0.6 + 0.2 * np.sin(i), 0.2, hue)
ax.add_patch(
Polygon(
polygon,
facecolor=color.to_hex(),
edgecolor="white",
linewidth=0.5,
alpha=0.8,
)
)
for point in points[: n_clusters * n_points_per_cluster]:
ax.scatter(
*point,
s=20,
c="white",
edgecolors="dc.nordic3",
linewidths=1,
zorder=10,
)
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_aspect("equal")
for s in ax.spines.values():
s.set_visible(False)
ax.set_facecolor("dc.nordic0")
ax.text(
0,
-11,
"Voronoi Dreams",
ha="center",
fontsize=dm.fs(3),
color="white",
weight="bold",
alpha=0.9,
)
dm.simple_layout(fig)
plt.show()
Total running time of the script: (0 minutes 2.621 seconds)