xxxxxxxxxx
77
// Data array to store color information
let data = [];
// UMAP instance
let umap;
// Boolean to check if UMAP is currently processing
let isUMAPRunning = false;
// Sliders for UMAP parameters
let nNeighborsSlider, minDistSlider;
function setup() {
// Setup canvas
createCanvas(400, 400);
colorMode(RGB, 255);
// Generate a dataset of random colors
for (let i = 0; i < 100; i++) {
data.push([random(255), random(255), random(255)]);
}
// Create a slider to adjust the number of neighbors in UMAP
nNeighborsSlider = createSlider(1, 50, 15);
// Rerun UMAP whenever the slider value changes
nNeighborsSlider.input(runUMAP);
// Create a slider to adjust the minimum distance in UMAP
minDistSlider = createSlider(0, 1, 0.1, 0.01);
// Rerun UMAP whenever the slider value changes
minDistSlider.input(runUMAP);
// Run UMAP initially with default slider values
runUMAP();
}
function draw() {
// Set background color
background(255);
// Process UMAP in each draw cycle
for (let i = 0; i < 100; i++) {
if (isUMAPRunning) {
let result = umap.step();
isUMAPRunning = result;
}
}
// Draw the UMAP embedding on the canvas
drawEmbedding();
}
// Function to initialize and run UMAP with current slider values
function runUMAP() {
umap = new UMAP({
nNeighbors: nNeighborsSlider.value(),
minDist: minDistSlider.value(),
nComponents: 2,
});
umap.initializeFit(data);
isUMAPRunning = true;
}
// Function to draw the UMAP embedding as circles on the canvas
function drawEmbedding() {
noStroke();
// Retrieve the current embedding from UMAP
let embedding = umap.getEmbedding();
for (let i = 0; i < embedding.length; i++) {
let data2D = embedding[i];
// Use the original color data for each point
fill(data[i][0], data[i][1], data[i][2]);
// Map the 2D UMAP output to canvas coordinates
let x = map(data2D[0], -10, 10, 0, width);
let y = map(data2D[1], -10, 10, 0, height);
// Draw a circle for each data point
circle(x, y, 10);
}
}