Public
Edited
Sep 15, 2024
Insert cell
Insert cell
Plot.plot({
width: 1500,
height: 600,
color: {
legend: true,
type: "ordinal",
scheme: "Turbo"
},
title: "Relative number of prime factors",
y: {
domain: [0, 0.75],
transform: (d, i) => d / i
},
marks: [
Plot.lineY(
primeFactors(2 ** 16),
Plot.mapY("cumsum", {
x: (_, i) => i,
y: 1,
stroke: (d) => d.length,
tip: true
})
)
]
})
Insert cell
{
let entries = _.range(2, 2 ** 12).map((n) => {
return {
n,
numFactors: allPrimeFactors[n].length,
largestFactor: _.max(allPrimeFactors[n])
};
});
return Plot.plot({
x: {
type: "log"
},
marks: [
Plot.dot(entries, {
x: "largestFactor",
y: "numFactors",
tip: true
})
]
});
}
Insert cell
Insert cell
{
let height = 1200;
let marginBottom = 30;
let marginTop = 30;
const yAxis = Plot.plot({
width: 40,
height,
marginTop,
marginBottom
});
let chart = Plot.plot({
width: 1500,
height,
axis: null,
color: {
scheme: "Inferno",
transform: (d) => Math.log2(d)
},
marks: [
Plot.dot(allPrimeFactors, {
x: (d, i) => i,
// fy: (d) => _.uniq(d).length,
fy: (d) => d.length,
// Sort by smoothness
y: (d) => Math.log2(_.max(d)),
// Sort by rad
// y: (d) => Math.log2(_.uniq(d).reduce((a, b) => a * b, 1)),
fill: (d) => _.max(d),
stroke: (d) => _.min(d),
strokeWidth: 0.5,
channels: { factors: (d) => d },
tip: true,
r: 2
// r: (d) => Math.sqrt(_.max(d))
})
]
});
chart.classList.add("chart");

const scrollbar = html`<div class="scrollbar">`;
scrollbar.append(chart);

const div = html`<div class="container">`;
div.append(yAxis, scrollbar);
return div;
}
Insert cell
Insert cell
{
let dim = 1000;
let pow = 9;
let factors = primeFactors(2 ** pow);
let ratio = 1 / Math.sqrt(2);
// let ratio = Math.sqrt(2) * Math.sin(Math.PI / 8);
let getPos = (n) => {
let r = dim * ratio ** (factors[n].length - 1);
let theta = ((n / 2 ** pow) * Math.PI) / 2;
let x = -r * Math.cos(-theta);
let y = -r * Math.sin(-theta);
return [x, y];
};
let margin = 10;
return svg`<svg width="${dim}" height="${dim}" viewbox="${-dim} ${0} ${dim} ${dim}">
${_.range(pow - 1).map((i) => {
return svg`<circle r="${
dim * ratio ** i
}" stroke="lightgrey" fill="none"/>`;
})}
${_.range(2, 2 ** pow)
.filter((i) => factors[i].length > 1)
.flatMap((i) => {
let [x1, y1] = getPos(i);
return _.uniq(factors[i]).map((f) => {
let q = i / f;
let [x2, y2] = getPos(q);
let path = `M ${x1} ${y1} L ${x2} ${y2}`;
let color = d3.interpolateRainbow(Math.log2(f) / pow);
return svg`<path d="${path}" stroke="${color}" fill="none" opacity=".5"/>`;
});
})}
${_.range(2, 2 ** pow).map((i) => {
let [x, y] = getPos(i);
return svg`<circle r="2" cx="${x}" cy="${y}" fill="black"/>`;
})}
</svg>`;
}
Insert cell
allPrimeFactors = primeFactors(2 ** 12)
Insert cell
import { primeFactors } from "@tesseralis/math"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more