Description
As pioneered by @jwoLondon, it's a sum of the density field at several harmonic bandwidths (1, 2, 4, 8, 16, 32, 64px) weighted by 1, 4, 9, 25, 36, 49.
I did a basic implementation (11 lines of code) as a spatial interpolator that iterates d3.blur2
https://observablehq.com/@fil/multiscale-density-spatial-interpolator.
(It could be seen as a new option for the density mark, or maybe we should subsume the density mark into a spatial interpolator + initializer.)
An advantage of using a spatial interpolator is that we can use it with the raster mark — we don't have to run a contouring algorithm. A disadvantage is that we don't get to set the color scale… but that can be fixed by using an initializer—which would also be necessary to normalize across facets.
There are a few more TODOs, listed in the notebook:
- to not ignore points outside the raster frame
- to add a weight option
We might want to scale the bandwidth (the "kilometer" in the original notebook is about 1.5 pixels, but it's complicated because d3.blur2 with a very small radius does not map linearly to the gaussian bandwidth… see https://observablehq.com/@d3/d3-blur for details).