This is a t-SNE representation of a 4-dimensional array of (random) colours. The t-SNE is computed by a javascript worker, using science.ai's implementation.
Forked from Fil's block: t-SNE worker
Built with blockbuilder.org, so double-thank-you to @enjalot.
See also t-SNE Voronoi
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
const width = 400,
x = d3.scaleLinear()
.domain([-200, 200])
.range([0, width]),
area = d3.area()
.x((d,i) => i)
.y0(width+90)
.y1((d,i) => width + 90 - parseInt(3 * d||0));
d3.queue()
.defer(d3.text, 'tsne.min.js')
.defer(d3.text, 'worker.js')
.await(function (err, t, w) {
const worker = new Worker(window.URL.createObjectURL(new Blob([t + w], {
type: "text/javascript"
})));
const data = d3.range(200).map(d => [Math.random(), Math.random(), Math.random(), Math.random()]);
const svg = d3.select('body').append('svg')
.attr('width', width + 100)
.attr('height', width + 100);
const circles = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('r', 4)
.attr('stroke-width', 0.3)
.attr('fill', d => d3.rgb(d[0] * 256, d[1] * 256, d[2] * 256))
.attr('stroke', d => d3.rgb(d[0] * 256, d[1] * 256, d[2] * 256))
.attr('opacity', d => 0.5 + 0.5 * d[3]);
const cost = svg.append('path')
.attr('fill', '#aaa');
let pos = data.map(d => [Math.random() - 0.5, Math.random() - 0.5]);
let costs = [];
d3.forceSimulation(data)
.alphaDecay(0.01)
.force('x', d3.forceX(0))
.force('y', d3.forceY(0))
.force('collide', d3.forceCollide(8))
.force('tsne', function(alpha){
data.forEach((d,i) => {
d.vx += 0.2 * (100*pos[i][0] - d.x);
d.vy += 0.2 * (100*pos[i][1] - d.y);
})
})
.on('tick', function () {
circles
.attr('cx', (d,i) => x(d.x))
.attr('cy', (d,i) => x(d.y));
cost.attr('d', area(costs));
});
worker.onmessage = function (e) {
if (e.data.pos) pos = e.data.pos;
if (e.data.iterations) {
costs[e.data.iterations] = e.data.cost;
}
};
worker.postMessage({
nIter: 400,
// dim: 2,
perplexity: 20.0,
// earlyExaggeration: 4.0,
// learningRate: 100.0,
// metric: 'euclidean',
data: data
});
});
</script>
</body>
https://d3js.org/d3.v4.min.js