Public
Edited
Jan 1, 2024
Insert cell
Insert cell
data = FileAttachment("penguins.csv").csv({ typed: true })
Insert cell
Plot.plot({
y: {grid: true},
color: {legend: true},
marks: [
Plot.rectY(data, Plot.binX({y: "count"}, {x: "flipper_length_mm", fill: "sex"})),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vecList = Promise.all(
icons.map(async (icon) => await binVecFromSvg(icon.svg, 12, 12))
)
Insert cell
Insert cell
Insert cell
function drawVecIcons(vecs) {
const canva = DOM.canvas(w, h);
const iconSize = 24;
const iconPerRow = w / iconSize;
canva.getContext("2d").clearRect(0, 0, w, h);
const ctx = canva.getContext("2d");
vecs.forEach(async (vec, idx) => {
const y = Math.floor(idx / iconPerRow);
const x = idx - y * iconPerRow;
drawBinaryImage2Ctx(ctx, vec, x * iconSize, y * iconSize);
});
return canva;
}
Insert cell
function simple_similarity(vec1, vec2) {
let acc = 0;
vec1.forEach((v, i) => {
acc += Math.abs(vec1[i] - vec2[i]);
});
return acc;
}
Insert cell
Insert cell
function binVecFromSvg(svg, width, height) {
return new Promise((resolve) => {
const context = DOM.context2d(width, height);
const img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0, width, height);
const vec = toBinaryImage(context.canvas);
resolve(vec);
URL.revokeObjectURL(img.src);
};
img.src = URL.createObjectURL(new Blob([svg], { type: "image/svg+xml" }));
});
}
Insert cell
function drawSvg2Bin(ctx, svg, gridX = 0, gridY = 0) {
const canvas = drawSvgToCtx(ctx, svg, gridX, gridY);
const vec = toBinaryImage(canvas);
return drawBinaryImage(vec);
}
Insert cell
function drawSvgToCanvas(svg, width, height) {
const context = DOM.context2d(width, height);

const img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0, width, height);
URL.revokeObjectURL(img.src);
};
img.src = URL.createObjectURL(new Blob([svg], { type: "image/svg+xml" }));

return context.canvas;
}
Insert cell
function drawBinaryImage(vec) {
const width = Math.floor(Math.sqrt(vec.length));
const height = width;
const context = DOM.context2d(width, height);

for (let i = 0; i < vec.length; i++) {
const x = i % width;
const y = Math.floor(i / width);
vec[i] === 0 && context.fillRect(x, y, 1, 1);
}

return context.canvas;
}
Insert cell
function drawBinaryImage2Ctx(ctx, vec, anchorX, anchorY) {
const width = Math.floor(Math.sqrt(vec.length));
const height = width;

for (let i = 0; i < vec.length; i++) {
const x = i % width;
const y = Math.floor(i / width);
vec[i] === 0 && ctx.fillRect(anchorX + x, anchorY + y, 1, 1);
}
}
Insert cell
function toBinaryImage(canvas) {
const rgba = canvas
.getContext("2d")
.getImageData(0, 0, canvas.width, canvas.height).data;
const vec = [];
for (let i = 0; i < rgba.length; i += 4) {
const r = rgba[i]; //r
const g = rgba[i + 1]; //g
const b = rgba[i + 2]; //b
const a = rgba[i + 3]; //a

const thresh = 128;
const black = r > thresh || g > thresh || b > thresh || a > thresh;

vec.push(black ? 0 : 1);
}
return vec;
}
Insert cell
Insert cell
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