Published
Edited
Nov 15, 2021
35 stars
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
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
normalDistributionGenerator = (location = 0, scale = 1) => {
return (x) => {
const left = 1 / (scale * Math.sqrt(2 * Math.PI))
const rightTop = -((x - location) ** 2)
const rightBottom = 2 * scale ** 2
return left * Math.exp(rightTop / rightBottom)
}
}
Insert cell
addKdeToArquero = aq => aq.addWindowFunction(
'kde',
{
create: (scale = 1, distributionGenerator = normalDistributionGenerator) => ({
init: state => state,
value: (w, f) => {
const normal = distributionGenerator(w.index, scale)
const windowSize = w.i1 - w.i0
// We use a range 3x as large as the dataset and "clamp" the
// values such that values to the left of the data are all equal
// to the earliest value and values to the right of the data
// are all equal to the last value.
// Technically this is only an approximation since a real normal
// distribution would be calculated over infinity
// TODO: If the data is sufficiently noisy a better approach might be
// to use some average of the first N points/last N points? A large
// outlier at the start or end could really throw this off.
return d3.range(w.i0 - windowSize, w.i1 + windowSize).reduce((acc, i) => {
// Left of window
if (i < w.i0) return acc + (w.value(w.i0, f) || 0) * normal(i)
// Right of window
if (i > w.i1) return acc + (w.value(w.i1, f) || 0) * normal(i)
// Inside window
return acc + (w.value(i, f) || 0) * normal(i)
}, 0)
},
}),
param: [1, 1],
},
// In case this cell gets run multiple times, we allow it to override itself.
// Unfortunately, cells using this function will not be updated until manually rerun.
{ override: true }
)
Insert cell
addKdeToArquero(aq)
Insert cell
Insert cell
casePlotWithOverlay = (data, overlayKey) => Plot.plot({
y: {
tickFormat: 's',
label: 'New Cases'
},
marks: [
Plot.areaY(data, {
x: 'date',
y: 'actuals.newCases',
fill: overlayKey ? '#CCC' : '#000'
}),
overlayKey ? Plot.line(data, {
x: 'date',
y: overlayKey,
stroke: '#069'
}) : null
],
height: 150
})
Insert cell
Insert cell
Insert cell
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