Published unlisted
Edited
Apr 14, 2022
1 fork
Insert cell
Insert cell
Loess = import("https://cdn.skypack.dev/loess@1")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.areaY(
data,
loess({
x: "x",
y: "y",
fill: "class",
fillOpacity: 0.2
})
),
Plot.line(
data,
loess({
x: "x",
y: "y",
stroke: "class",
strokeWidth: 2
})
),
Plot.dot(data, { x: "x", y: "y", fill: "class" })
],
y: { domain: [-1.8, 1.8] }
})
Insert cell
loess = ({ x, y, ...options }) => {
const z = options.z ?? options.fill ?? options.stroke; // TODO maybeZ; strict undefined
const [X, setX] = Plot.column(x);
const [Y, setY] = Plot.column(y);
const [Y1, setY1] = Plot.column(y);
const [Y2, setY2] = Plot.column(y);
return {
...Plot.transform(options, function (data, facets) {
const X = setX(Plot.valueof(data, x));
const Y = setY(Plot.valueof(data, y));
const Z = Plot.valueof(data, z);
const Y1 = setY1(new Float64Array(X.length));
const Y2 = setY2(new Float64Array(X.length));
for (const facet of facets) {
for (const I of Z ? d3.group(facet, (i) => Z[i]).values() : [facet]) {
const model = new Loess.default(
{ x: I.map((i) => X[i]), y: I.map((i) => Y[i]) },
{ span, band, degree }
).predict();
for (const [j, i] of I.entries()) {
Y[i] = model.fitted[j];
Y1[i] = model.fitted[j] - model.halfwidth[j];
Y2[i] = model.fitted[j] + model.halfwidth[j];
}
}
}
return { data, facets };
}),
x: X,
y: Y,
y1: Y1,
y2: Y2
};
}
Insert cell
data = {
const n = 150;
return d3.range(n).map((i) => ({
x: i / (n - 1),
class: String.fromCharCode(64 + (i % 3)),
y:
Math.sin((3 + (i % 3)) * Math.PI * (i / (n - 1))) + (Math.random() - 0.5),
w: Math.random()
}));
}
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