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

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