Public
Edited
Mar 31, 2024
Importers
26 stars
SQLite Geospatial - intersections!London Isodemographic CartogramGolden Tonal Palette AnalysisHexbin Transform / Observable Plot
NBA Finals, Game 4
Disk Sampling on a SphereNBA Finals, Game 1Build your first scatterplot with Observable PlotDisplaying IBM Carbon charts in ObservableModelo de Cúpula CatenáriaBivariate Bubble MapAnalyzing Star Wars movies + the first anniversary of Observable Plot!Single-family homes owned by large corporate landlords in North CarolinaThe MoMA Collection DataMapping the Vietnamese DiasporaElection map as striped circles #2They heard the callDiagrammatic EmbeddingsHegel's Complete System of PhilosophyGeneration Arc DiagramVulnerability of Mountain PeoplesVisualizing Air Raid Sirens in UkraineUkrainian refugees welcomeConcentric Circles in D3Daylight Saving Time Gripe Assistant ToolPerceptually uniform color models and their implications
Top Notebooks of February 2022Zillow Home PricesBlack History Month ActivityExamples from: Three Simple Flexible tools for Empowered Data VisualizationFull Covid Vaccination Rate in CA by County Over TimePlot CheatsheetsHunga Tonga–Hunga Ha'apai Global Pressure WaveVisualizing The New York Times’s Mini Crossword100 Beautiful and Informative Notebooks of 2021When Presidents Fade AwayThe Most Frequently Used Emoji of 2021Upset Plots with Observable PlotLucy mission animationSpreadsheet-based data collaboration gets supercharged with Observable30 Day Map Challenge: Day 4 - HexagonsDisputed territoriesMapping the Cities of US Highway SignsThirty day Map Challenge: Day 1 - PointsCube Pushing Loop 💪 🧊 🔄Guided Tour of an Infinite Sphere GridCanvas, P5.js and circle packing (collision and cluster force) on a mapWomen's History Month DataViz ContestWomen in DataViz EventSVG flowersMultiple Set Venn with Color BlendingA Stupid Emoji Utility FunctionQuilting with d3-curveCurvilinear RosettesStrange AttractorsSolo board gameDouble pendilumVertical SlidersDrawing and animating blobs with svg and javascriptOrbiting Particles III#genuary 2021 ~ Do some golf!Imitation Game 🖐Happy New Year (2019) (And other celebrations)Earth Temperature SpiralStar MapCorrelation FilteringBattle of ColorsPapercraft Christmas Ornaments GeneratorChristmas Tree Perspective 🎄bouncing circles2D (Non-physical) N-body Gravity with Poisson's EquationWaterfall Fill2020 TimelineTime Spiral with a COVID DemoTransition between Three.js camerasJulio Le Parc Replications and VariationsFlexible HeatmapSquare PackingSierpiński curve animationTrainsWhy use a radial data visualization?Earthquakes from the past 30 daysThe US COVID SyringeHello OGL - Minimal WebGL libraryVersor MultiplicationLabyrinthTruncated-octahedron-based 3D-space-filling curveNUTS regions (The Nomenclature of territorial units for statistics): PerspectiveStretchy FishTP3: Power Diagram and Semi-Discrete Optimal TransportEmoji ParticlesFirma de color de BogotáCovid19 WorldwideWeb 3.0 Explorable # 3: NFTs -- Game Items With Real World ValueUnemployment ExplorationSierpinski curveEight QueensVoronoi StipplingSpinning out of controlFragment shader raytracerSunny day, rainy day in SeattleAs votes are countedOrbit of the dayVoronoi ClothTry to impeach this? Challenge accepted!Dispersion in Water Surface Waves
Self-Organizing Maps meet Delaunay
Generative ArtReturn to a squareCreating a Canvas Noise Map for Generative ArtMARTINI: Real-Time RTIN Terrain MeshMunsell spinGenerative artAs votes come in, what would it take for the trailing candidate to win?3a. Historical participation in early voting vs. Election Day votingWaffle ChartSun settingRaymarch HelperF1 Constructor Standings 2010-2019Electoral College Decision TreeThe Woman Citizen's Wheel of Progress, 1917Equisurface bull's eye
Insert cell
Insert cell
Insert cell
dimensions = ["r", "g", "b"]
Insert cell
randomDatum = () =>
Object.fromEntries(dimensions.map(d => [d, Math.random() * 255]))
Insert cell
data = Array.from({ length: 3000 }, randomDatum)
Insert cell
distance = (a, b) => Math.hypot(...dimensions.map(d => a[d] - b[d]))
Insert cell
Insert cell
neurons = Array.from({ length: 308 }, randomDatum, replay)
Insert cell
Insert cell
positions = neurons.map(randomPoint) // see implementation below
Insert cell
voronoi = d3.Delaunay.from(positions).voronoi([0, 0, width, height])
Insert cell
// Any function or generator that lists the neighbors of a node is good to use
// see https://observablehq.com/@d3/voronoi-neighbors
neighbors = i => voronoi.neighbors(i)
Insert cell
Insert cell
bmu = d => d3.leastIndex(neurons, u => distance(u, d))
Insert cell
Insert cell
learning_rate = .1
Insert cell
function step(i) {
const d = data[i];

// find the BMU and update it
const u = bmu(d);
update_neuron(u, d, learning_rate);

// update its neighbors too, more gently
for (const n of neighbors(u)) update_neuron(n, d, .25 * learning_rate);

return u;
}
Insert cell
function update_neuron(u, d, alpha) {
const a = neurons[u];
for (const i of dimensions) a[i] += alpha * (d[i] - a[i]);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function* run() {
const t = 1 / 200, // sampling for change%
target = 0.05; // target change%
let change = 1,
i = 0;
do {
// select a data point to update
const n = i++ % data.length;
const u = step(n);

// log the number of unhappy data points
change = (change + t * (u !== bmus[n])) / (1 + t);
bmus[n] = u;

// draw this step (progressive time)
if (Math.sqrt(i) % 1 === 0) {
draw();
yield `step ${i}, change rate: ${(change * 100).toFixed(1)}%`;
}

// stop when less than 5% of the recently examined data points are unhappy
} while (change > target && i < 100000);

draw();
yield `stopped after ${i} steps, change: ${(change * 100).toFixed(1)}%`;
}
Insert cell
Insert cell
Insert cell
Insert cell
randomPoint = {
const positions = [...pick2d(width + 30, height, neurons.length, topology)];
return (_, i) => [
positions[i % positions.length][0],
positions[i % positions.length][1] + Math.random()
];
}
Insert cell
bmus = (neurons, Int32Array.from(data).fill(-1))
Insert cell
mutable replay = -1 // ensure neurons, positions, bmus are reset
Insert cell
(show, draw()) // redraw the map when the color selector is clicked
Insert cell
height = 600
Insert cell
import { pick2d } from "@fil/2d-point-distributions"
Insert cell
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