Scatter Plots on Tile Maps in JavaScript

How to make scatter plots on tile maps in Plotly.JS


New to Plotly?

Plotly is a free and open-source graphing library for JavaScript. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.

var data = [{
  type:'scattermap',
  lat:['45.5017'],
  lon:['-73.5673'],
  mode:'markers',
  marker: {
    size:14
  },
  text:['Montreal']
}]

var layout = {
  autosize: true,
  hovermode:'closest',
  map: {
    bearing:0,
    center: {
      lat:45,
      lon:-73
    },
    pitch:0,
    zoom:5
  },
}

Plotly.newPlot('myDiv', data, layout)
d3.csv('https://raw.githubusercontent.com/bcdunbar/datasets/master/meteorites_subset.csv', function(err, rows){

  var classArray = unpack(rows, 'class');
  var classes = [...new Set(classArray)];

  function unpack(rows, key) {
    return rows.map(function(row) { return row[key]; });
  }

  var data = classes.map(function(classes) {
    var rowsFiltered = rows.filter(function(row) {
        return (row.class === classes);
    });
    return {
       type: 'scattermap',
       name: classes,
       lat: unpack(rowsFiltered, 'reclat'),
       lon: unpack(rowsFiltered, 'reclong')
    };
  });

  var layout = {
	 title: 'Meteorite Landing Locations',
	 font: {
		 color: 'white'
	 },
    dragmode: 'zoom',
    map: {
      center: {
        lat: 38.03697222,
        lon: -90.70916722
      },
      domain: {
        x: [0, 1],
        y: [0, 1]
      },
      style: 'dark',
      zoom: 1
    },
    margin: {
      r: 20,
      t: 40,
      b: 20,
      l: 20,
      pad: 0
    },
    paper_bgcolor: '#191A1A',
    plot_bgcolor: '#191A1A',
    showlegend: true,
	 annotations: [{
		 x: 0,
       y: 0,
       xref: 'paper',
       yref: 'paper',
		 text: 'Source: <a href="https://data.nasa.gov/Space-Science/Meteorite-Landings/gh4g-9sfh" style="color: rgb(255,255,255)">NASA</a>',
		 showarrow: false
	 }]
  };

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

 scl = [[0, 'rgb(150,0,90)'],[0.125, 'rgb(0, 0, 200)'],[0.25,'rgb(0, 25, 255)'],[0.375,'rgb(0, 152, 255)'],[0.5,'rgb(44, 255, 150)'],[0.625,'rgb(151, 255, 0)'],[0.75,'rgb(255, 234, 0)'],[0.875,'rgb(255, 111, 0)'],[1,'rgb(255, 0, 0)']];

    var data = [{
        type: 'scattermap',
        mode: 'markers',
        text: unpack(rows, 'Globvalue'),
        lon: unpack(rows, 'Lon'),
        lat: unpack(rows, 'Lat'),
        marker: {
          color: unpack(rows, 'Globvalue'),
          colorscale: scl,
          cmin: 0,
          cmax: 1.4,
          reversescale: true,
          opacity: 0.5,
          size: 3,
          colorbar:{
            thickness: 10,
            title: {side:
              'right'
            },
            outlinecolor: 'rgba(68,68,68,0)',
            ticks: 'outside',
            ticklen: 3,
            shoticksuffix: 'last',
            ticksuffix: 'inches',
            dtick: 0.1
          }
        },
        name: 'NA Precipitation'
    }];

    layout = {
      dragmode: 'zoom',
      map: {
        center: {
          lat: 38.03697222,
          lon: -90.70916722
        },
        domain: {
          x: [0, 1],
          y: [0, 1]
        },
        style: 'light',
        zoom: 3
      },
      margin: {
        r: 0,
        t: 0,
        b: 0,
        l: 0,
        pad: 0
      },
      showlegend: false
   };

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

    function getMaxOfArray(numArray) {
        return Math.max.apply(null, numArray);
    }

    var data = [];
    var count = unpack(rows, 'cnt');
    var startLongitude = unpack(rows, 'start_lon');
    var endLongitude = unpack(rows, 'end_lon');
    var startLat = unpack(rows, 'start_lat');
    var endLat = unpack(rows, 'end_lat');

    for ( var i = 0 ; i < count.length; i++ ) {
        var opacityValue = count[i]/getMaxOfArray(count);

        var result = {
            type: 'scattermap',
            lon: [ startLongitude[i] , endLongitude[i] ],
            lat: [ startLat[i] , endLat[i] ],
            mode: 'lines',
            line: {
                width: 1,
                color: 'red'
            },
            opacity: opacityValue
        };

        data.push(result);
    };

    layout = {
      dragmode: 'zoom',
      map: {
        center: {
          lat: 38.03697222,
          lon: -90.70916722
        },
        domain: {
          x: [0, 1],
          y: [0, 1]
        },
        style: 'dark',
        zoom: 2
      },
      margin: {
        r: 0,
        t: 0,
        b: 0,
        l: 0,
        pad: 0
      },
      paper_bgcolor: '#191A1A',
      plot_bgcolor: '#191A1A',
      showlegend: false
   };

  Plotly.newPlot("myDiv", data, layout, {showLink: false});

});

This example uses symbol attribute to set the marker symbol.

var data = [
	{
		type: "scattermap",
		mode: "markers+text+lines",
		lon: [-75, -80, -50],
		lat: [45, 20, -20],
		marker: { size: 20, symbol: ["bus", "harbor", "airport"] },
		text: ["Bus", "Harbor", "Airport"],
		textposition: "bottom right"
	}
];

var layout = {
	map: { style: "outdoors", zoom: 0.7 },
	showlegend: false, height: 500, width: 700
};

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

> Mapbox traces are deprecated and may be removed in a future version of Plotly.js.

Earlier examples use traces that render with Maplibre GL JS. These traces were introduced in Plotly.js 2.35.0 and replace Mapbox-based tile maps, which are now deprecated. Here's one of the earlier examples using the Mapbox-based choroplethmapbox trace

var data = [{
  type:'scattermapbox',
  lat:['45.5017'],
  lon:['-73.5673'],
  mode:'markers',
  marker: {
    size:14
  },
  text:['Montreal']
}]

var layout = {
  autosize: true,
  hovermode:'closest',
  mapbox: {
    bearing:0,
    center: {
      lat:45,
      lon:-73
    },
    pitch:0,
    zoom:5
  },
}

Plotly.setPlotConfig({
  mapboxAccessToken: "your access token"
})

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