UMAP first builds a k-nearest-neighbor graph in the original high-dimensional space (here: 4 synthetic Gaussian blobs in 6D, k = n_neighbors, distances measured on the real 6D coordinates — never on the 2D layout). It then optimizes a low-dimensional layout — 2D on this canvas — so that the graph's structure survives the drop in dimension, using two competing forces applied every epoch:
attractive (per graph edge i–j, k-NN in 6D):
F = k_a · (d(i,j) − restLength) · û(i→j)
restLength ∝ min_dist (small min_dist ⇒ tighter clusters)
repulsive (sampled non-neighbor pairs — negative sampling, as in real UMAP):
F = k_r / (d(i,j)² + ε) · û(j→i) (inverse-square push-apart)
centering: a weak pull toward the origin keeps the cloud in view.
This mirrors the real UMAP objective at a qualitative level: attraction shrinks connected pairs toward a target separation set by min_dist, while the inverse-square repulsion term has the same leading-order shape as UMAP's actual negative-sampling gradient, which pushes unrelated points apart in the embedding. Increasing n_neighbors connects more distant points, favoring global structure over fine local detail; increasing min_dist relaxes how tightly connected points are allowed to pack. Squeezing 6 real dimensions into 2 is strictly harder than into 3 — that's exactly why this demo runs a real 2D negative-sampling budget instead of an exhaustive all-pairs sum, closer to what production UMAP actually does at scale.
- Layout stress — mean squared deviation of each edge's current length from its target; falls as the layout converges.
- Neighbor preservation — of each point's original k nearest neighbors (measured in the true 6D data), the fraction still among its k nearest neighbors in the current 2D embedding, recomputed exactly (not sampled) every half-second from the live positions. Measured runs of this exact algorithm (negative-sampling repulsion included) start near 11-13% from random initialization and converge to roughly 65-70% after several thousand epochs — a real, non-trivial recovery of 6D neighborhood structure from 2 surviving dimensions.
- New Data resamples four fresh 6D Gaussian blobs and restarts the embedding from random noise; Reset Layout keeps the same data but re-randomizes only the embedding positions.