Leaflet heatmap options considered

I mentioned wanting a heatmap for some geographic data. Leaflet has a variety of heatmap plugins, I spent a couple of hours looking at them.

First, a word about heatmaps. A true heatmap has a feature where if you keep adding points (“heat”) to a spot, that heat diffuses and spreads out. In theory you could cover the whole world in hot red just adding to a single lat/lon because the heat diffuses (unless you have cooling/decay enabled). I want this feature. Calculating diffusion like this is complicated and slow. So most “heatmaps” cheat and instead of running a diffusion algorithm just draw blurry transparent dots. When they overlap it looks a lot like a heatmap, but you never get the full diffusion. It’s a reasonable compromise for a lot of applications (and way faster, particularly since it’s GPU-friendly) but it’s a compromise I’m hoping to avoid. See also this technical discussion.

Another key thing is how map zooming is handled. The heat blobs are really rendered in terms of pixels, not meters or geographic degrees, so the heatmap picture needs to be re-rendered at every zoom level. Some of the libraries look like they just render one image and raster scale it to match the zoom. The behavior I want is visible in this demo: notice how the blobs get more detailed when you zoom in.

Anyway, here’s my quick review of the 7 plugins:

  • Leaflet.heat; first one I’ve used. Canvas based, seems to work for 20,000 points no problem. Not a true heatmap, just fuzzy circles, but it looks good. Last update a year ago.
  • heatmap.js: canvas based, I think a true heatmap. Demo doesn’t recalculate on zoom the way I want and I don’t think there’s code for doing it. The library is mostly used for rendering user attention on web pages.
  • webgl-heatmap-leaflet. I gotta think WebGL is a good idea. New code, mostly 3 months old. Unfortunately it doesn’t seem to have the zooming behavior I want. There’s some scaling code (units and size option) but that seems to be about projecting circles of a consistent size at different latitudes.
  • Leaflet-solr-heatmap, see examples here. It’s pretty impressive being able to handle 10M points but the grid display isn’t what I’m looking for.
  • leaflet-div-heatmap is clever for using CSS and divs. No live demo I could find though, and no commits in 4 years, so I stopped looking.
  • MaskCanvas: not a heatmap, more of a “reveal the map” display. It’s neat though! Last real update was 2 years ago.
  • HeatCanvas: true heatmap, a bit too oriented towards static images. Not sure if it works well in zooming. Last real update was 4 years ago, I didn’t look further.

In summary: Leaflet.heat is the one I want. It’s the only library that recalculates on zoom. The downside is it’s not a true heatmap. I think that actually matters for my application (I expect a lot of dwell time in one place) but it’s a compromise I can accept.

Worth keeping an eye on mourner’s WebGL work for mapbox.js too; I’d rather just use vanilla Leaflet though. But his demo looks great.