Published
Edited
Mar 8, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
//
// Computes data structures for mapping category names to integer numbers
// and vice-versa
//
function categoryMaps(categorical) {
let indexToCat = {};
let catToIndex = {};
let dimensions = getDimensions(categorical);
for (let dim of dimensions) {
indexToCat[dim] = [];
catToIndex[dim] = new Map();
}
for (let row of categorical) {
for (let dim of dimensions) {
if (!catToIndex[dim].has(row[dim])) {
catToIndex[dim].set(row[dim], indexToCat[dim].length);
indexToCat[dim].push(row[dim]);
}
}
}
return { indexToCat, catToIndex };
}
Insert cell
data = titanic
Insert cell
//
// Transforms data to a tensor adding two additional dimensions which are random samples of a unit disk
//
tensor = {
return tf.tensor(
data.map(row => {
const a = Math.random() * 2 * Math.PI;
const r = Math.sqrt(Math.random());
return dimensions
.map(d => catToIndex[d].get(row[d]))
.concat([r * Math.cos(a), r * Math.sin(a)]);
})
);
}
Insert cell
catMaps = categoryMaps(data)
Insert cell
indexToCat = catMaps.indexToCat
Insert cell
catToIndex = catMaps.catToIndex
Insert cell
getDimensions = categorical => Object.keys(categorical[0])
Insert cell
dimensions = getDimensions(data)
Insert cell
colorDimensionIndex = dimensions.lastIndexOf(colorDimension)
Insert cell
textureDimensionIndex = dimensions.lastIndexOf(textureDimension)
Insert cell
Insert cell
function makePalette(scale, ncolors) {
let palette = [];
for (let i = 0; i < ncolors; i++) {
palette.push(scale((1 + i) / (ncolors + 1)));
}
return palette;
}
Insert cell
Insert cell
dimPalette = makePalette(
dimensionScales[colorDimensionIndex],
indexToCat[colorDimension].length
)
Insert cell
texturePalette = makePalette(
dimensionScales[textureDimensionIndex],
indexToCat[textureDimension].length
)
Insert cell
Insert cell
coords = {
const ts = await tf.tsne(tensor);

await ts.iterateKnn(ts.knnIterations());

const tsneIterations = 333;
for (let i = 0; i < tsneIterations; ++i) {
await ts.iterate(3);
yield ts.coordsArray();
}
}
Insert cell
Insert cell
import { data as titanic } from "@john-guerra/parallel-sets"
Insert cell
d3 = require("d3@6")
Insert cell
import { Radio } from "@observablehq/inputs"
Insert cell
import { swatches } from "@d3/color-legend"
Insert cell
import { ramp, scales, displayPalettes } from "@makio135/give-me-colors"
Insert cell
//
// Require "black magic" to import tensor flow core and the tsne tf module
// (Thanks @Fil)
//
tf = {
replay;
const r = require.alias({
"@tensorflow/tfjs-core": "@tensorflow/tfjs-core@0.14.3",
"@tensorflow/tfjs-tsne": "@tensorflow/tfjs-tsne@0.2.0"
});
const [tf, tsne] = await Promise.all([
r("@tensorflow/tfjs-core"),
r("@tensorflow/tfjs-tsne")
]);
tf.tsne = tsne.tsne;
return tf;
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more