Spatial heatmaps with Folium in Python

In previous posts I have demonstrated how one can geocode data and plot markers using Geopy and Folium in Python. I have also demonstrated heatmapping workflows in R, using packages such as Leaflet.

In this post I want to use the Leaflet.js library for creating a heatmap via the Folium module in Python.

I provide a script for doing so below. The script reads in a csv file with location names and addresses. Using Geopy and the Nominatim geocoding service this list of locations gets geocoded, returning coodinates by latitude and longitude. The csv-file contains a metric value for each location. This metric defines the color intensity of the heatmap.

Below lines of code are used for reading in the csv file and geocoding its location entries into latitudes and longitudes. A glimpse of the final pandas DataFrame is provided:

# import relevant packages / modules
import pandas
import folium
from folium.plugins import HeatMap
# read in csv file containing location data
data = pandas.read_csv("heatmap.csv")
# merging country, city and street into a single address string
data["addresses"] = data["country"] + ", " + data["city"] + ", " + data["street "]
# import the geopy module
import geopy
# create a service object
service = geopy.Nominatim(user_agent = "myGeocoder")
# geocode every address, using .apply() methode for pandas DataFrame
from geopy.extra.rate_limiter import RateLimiter
data["coordinates"] = data["addresses"].apply(RateLimiter(service.geocode,min_delay_seconds=1))
# display glimpse of geocoded pandas DataFrame table
data.head()
countrycitystreetmetricaddressescoordinates
0GermanyBerlinAlexanderplatz 110Germany, Berlin, Alexanderplatz 1(Alexanderstraße, Spandauer Vorstadt, Mitte, B…
1GermanyBerlinDircksenstrasse 25Germany, Berlin, Dircksenstrasse 2(2, Dircksenstraße, Luisenstadt, Mitte, Berlin…
2GermanyBerlinRathausstrasse 116Germany, Berlin, Rathausstrasse 1(1-14, Rathausstraße, Spandauer Vorstadt, Mitt…
3GermanyBerlinRosa-Luxemburg-Strasse 211Germany, Berlin, Rosa-Luxemburg-Strasse 2(2, Rosa-Luxemburg-Straße, Scheunenviertel, Mi…
4GermanyBerlinMemhardstrasse 88Germany, Berlin, Memhardstrasse 8(8, Memhardstraße, Scheunenviertel, Mitte, Ber…

Using the geocided DataFrame I create a folium heatmap:

# extracting longitude and latitude values to separate lists
longs = [coord.longitude for coord in data["coordinates"]]
lats = [coord.latitude for coord in data["coordinates"]]
# calculating mean longitude and latitude values
import statistics
meanLong = statistics.mean(longs)
meanLat = statistics.mean(lats)
# create base map object using Map()
mapObj = folium.Map(location=[meanLat, meanLong], zoom_start = 14.5)
# create heatmap layer
heatmap = HeatMap( list(zip(lats, longs, data["metric "])),
                   min_opacity=0.2,
                   max_val=data["metric "].max(),
                   radius=50, blur=50, 
                   max_zoom=1)
# add heatmap layer to base map
heatmap.add_to(mapObj)
mapObj

You May Also Like

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.