Tile Density Heatmap in JavaScript

How to make a tile-based density heatmap in JavaScript. A density heatmap uses a variable binding expression to display population density.


Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Try Plotly Studio now.

var data = [
  {type: "densitymap", lon: [10, 20, 30], lat: [15, 25, 35], z: [1, 3, 2],
   radius: 50, colorbar: {y: 1, yanchor: 'top', len: 0.45}},
  {type: 'densitymap', lon: [-10, -20, -30], lat: [15, 25, 35],
   radius: [50, 100, 10],  colorbar: {y: 0, yanchor: 'bottom', len: 0.45}
  }];

var layout = {map: {style: 'light', center: {lat: 20}}, width: 600, height: 400};

Plotly.newPlot('myDiv', data, layout);
d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv',
  function(err, rows){function unpack(rows, key) {return rows.map(function(row){ return row[key];
})};

var data = [{
  lon: unpack(rows, 'Longitude'), lat: unpack(rows, 'Latitude'), radius:10,
  z: unpack(rows, 'Magnitude'), type: "densitymap", coloraxis: 'coloraxis',
  hoverinfo: 'skip'}];

var layout = {
    map: {center: {lon: 60, lat: 30}, style: "outdoors", zoom: 2},
    coloraxis: {colorscale: "Viridis"}, title: {text: "Earthquake Magnitude"},
    width: 600, height: 400, margin: {t: 30, b: 0}};

Plotly.newPlot('myDiv', data, layout);
})

As well as the built-in style names, layout.map.style accepts the URL of any MapLibre style definition. The example below points at Carto's Positron style JSON directly.

Some providers require an API key, which you append to the style URL. The stamen-terrain, stamen-toner, and stamen-watercolor style names are not built in for this reason: Stamen tiles are served by Stadia Maps, which requires an account. To use them, sign up and add your own key:

map: {style: 'https://tiles.stadiamaps.com/styles/stamen_watercolor.json?api_key=YOUR_STADIA_KEY'}
var data = [{type: 'densitymap', lon: [10, 20, 30], lat: [15, 25, 35], z: [1, 3, 2]}];

var layout = {
  width: 600,
  height: 400,
  map: {style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json'}
};

Plotly.newPlot('myDiv', data, layout);