Heat map on a map (spatial heat map) in plotly

Sample data set

The data set used on the following examples represents the population for each census section of Galicia, an autonomous community of Spain. The coordinates are given by the centroid of each census section.

import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

Heat maps with density_map

Given a data frame with coordinates and a value assigned to each point it is possible to create dynamic spatial heatmaps in Python with plotly. For this purpose you can make use of the density_map function from plotly express. In the examples below we are going to use population data, but this kind of chart is very interesting for visualizing different types of data like earthquakes data, phone signal data, road congestion, etc.

The density_map function requires several input arguments: the latitude (lat), the longitude (lon), the values for each coordinate (z) . Optionally, you can also set the map style (map_style), the influence radius for each point (radius. Defaults to 10), the zoom level (zoom. Between 0 and 20, defaults to 8), the center point of the map (center) and other additional parameters (like width, height, opacity, etc.).

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob',
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'open-street-map')
fig.show()

Since plotly 5.24 the tile map functions (scatter_map, density_map, choropleth_map…) are based on MapLibre and don’t need any token. They replace the old *_mapbox functions, which were deprecated and removed in plotly 7. The available styles for map_style are 'basic' (default), 'streets', 'outdoors', 'light', 'dark', 'satellite', 'satellite-streets', 'open-street-map', 'white-bg', 'carto-positron', 'carto-darkmatter' and 'carto-voyager' (the last three also have a version without labels, such as 'carto-positron-nolabels').

Map styles

The following examples show some of the available map styles:

white-bg

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'white-bg')
fig.show()

carto-positron

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'carto-positron')
fig.show()

carto-darkmatter

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'carto-darkmatter')
fig.show()

outdoors

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'outdoors')
fig.show()

dark

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'dark')
fig.show()

satellite-streets

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob')
                        radius = 8,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'satellite-streets')
fig.show()

Color and opacity

You can override the default color palette used for the spatial heatmap with the color_continuous_scale argument of the function. You can input a list of valid colors, but you can also set a predefined continuous color palette from plotly. The list of available color palettes is displayed below:

import plotly.express as px

px.colors.named_colorscales()

# Named plotly continuous color palettes:

# ['aggrnyl', 'agsunset', 'blackbody', 'bluered', 'blues', 'blugrn', 'bluyl', 'brwnyl',
# 'bugn', 'bupu', 'burg', 'burgyl', 'cividis', 'darkmint', 'electric', 'emrld', 'gnbu',
# 'greens', 'greys', 'hot', 'inferno', 'jet', 'magenta', 'magma', 'mint', 'orrd', 'oranges',
# 'oryel', 'peach', 'pinkyl', 'plasma', 'plotly3', 'pubu', 'pubugn', 'purd', 'purp', 'purples',
# 'purpor', 'rainbow', 'rdbu', 'rdpu', 'redor', 'reds', 'sunset', 'sunsetdark', 'teal', 'tealgrn',
# 'turbo', 'viridis', 'ylgn', 'ylgnbu', 'ylorbr', 'ylorrd', 'algae', 'amp', 'deep', 'dense', 'gray',
# 'haline', 'ice', 'matter', 'solar', 'speed', 'tempo', 'thermal', 'turbid', 'armyrose', 'brbg',
# 'earth', 'fall', 'geyser', 'prgn', 'piyg', 'picnic', 'portland', 'puor', 'rdgy', 'rdylbu', 'rdylgn',
# 'spectral', 'tealrose', 'temps', 'tropic', 'balance', 'curl', 'delta', 'oxy', 'edge',
# 'hsv', 'icefire', 'phase', 'twilight', 'mrybm', 'mygbm']

Now you can set the desired palette:

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob',
                        radius = 7,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'open-street-map',
                        color_continuous_scale = 'rainbow')
fig.show()

Color opacity

The colors can hide important information on the map, e.g., the name of a city. If you want, you can customize the transparency of the colors with opacity, which ranges from 0 (transparent) to 1 (opaque).

import pandas as pd
import plotly.express as px

# Data with latitude/longitude and values
df = pd.read_csv('https://raw.githubusercontent.com/R-CoderDotCom/data/main/sample_datasets/population_galicia.csv')

fig = px.density_map(df, lat = 'latitude', lon = 'longitude', z = 'tot_pob',
                        radius = 7,
                        center = dict(lat = 42.83, lon = -8.35),
                        zoom = 6,
                        map_style = 'open-street-map',
                        color_continuous_scale = 'rainbow',
                        opacity = 0.5)
fig.show()
Storytelling with Data

A Data Visualization Guide for Business Professionals

Buy on Amazon
Data Sketches

A journey of imagination, exploration, and beautiful data visualizations

Buy on Amazon

See also