Publish AI, ML & data-science insights to a global community of data professionals.

Creating Geospatial Heatmaps With Python’s Plotly and Folium Libraries

Two Great Python Options for Visualising Geospatial Variation

Photo by KOBU Agency on Unsplash
Photo by KOBU Agency on Unsplash

Heatmaps, also known as Density Maps, are data visualizations that display the spatial distribution of a variable across a geographic area. They can be great tools for visualising and identifying trends, supporting decision-making, detecting outliers, and creating compelling visualisations for presentations.

There are several mapping python libraries available, however, two very popular and easy to use libraries are Folium and Plotly Express.

Folium is a great library that makes it easy to visualise geospatial data. It is powered by Leaflet.js, which is a leading javascript mapping library and is platform-independent. Plotly is a popular library for creating powerful interactive data visualisations with very few lines of code and can be used to create interactive maps with MapBox.

Within this article, we will see how we can use these two libraries to visualise acoustic compressional slowness data on the Norwegian Continental Shelf.

A video version of this tutorial using Plotly Express can be found on my YouTube channel. Check it out below.

Importing Libraries and Loading Data

For this tutorial, we will start with importing pandas, which will be used to load our data from a CSV file.

import pandas as pd

The dataset we are using for this tutorial is a combination of the following:

  • The Xeek Force 2020 Machine Learning lithology competition dataset was used to derive an average acoustic compressional slowness (DTC) value for the Shetland Group
  • Data from the Norwegian Petroleum Directorate website, which was used to provide the location data
df = pd.read_csv('xeek_force_2020_dtc_mapping.csv')
df

When the data has been loaded, we can call upon the dataframe with the following:

Dataframe view of wells on the Norwegian Continental Shelf. Image by the author.
Dataframe view of wells on the Norwegian Continental Shelf. Image by the author.

We can see that we have 7 columns:

  • Well Name – Name of the Well
  • DTC – Average acoustic compressional slowness for the Shetland Group
  • Temperature – Bottom hole temperate for the well
  • Water Depth -Depth of seabed from sea level
  • Completion Year – Year the well was completed
  • Latitude – Latitude position of the well in decimal units
  • Longitude – Longitude position of the well in decimal units

Creating a Heatmap with Plotly Express

To begin creating the heatmap with Plotly Express, we need to import the library into our notebook like so:

import plotly_express as px

We then need to create a new figure. This is done by calling upon plotly express’s density_mapbox .

To create our map, we need to pass in a few parameters:

  • df – the name of the dataframe with the data
  • lat – the name for the latitude column
  • lon – the name for the longitude column
  • z – the name of the column containing the data we want to visualise on the heatmap
  • center – the position where the map will be centred upon. We can call upon the mean of the latitude and longitude columns
  • zoom – the initial zoom level of the map

The last two parameters mapbox_style and height control the background mapping layer and the height of the plot.

fig = px.density_mapbox(df, lat='Latitude', lon='Longitude',
                        z='DTC', radius=20,
                        center=dict(lat=df.Latitude.mean(), 
                                    lon=df.Longitude.mean()), 
                        zoom=4,
                        mapbox_style="open-street-map", 
                        height=900)
fig.show()

When we call upon fig.show() we get back the following map.

Heatmap generated using density_mapbox from plotly express. Image by the author.
Heatmap generated using density_mapbox from plotly express. Image by the author.

From this map, we can see that we have higher values of DTC in the northern end of the region, which could be attributable to several things, including lower compaction or increased shalieness.

The great thing about the map generated by plotly express is that we can hover over the data and get the values for the plotted variable (DTC). This is done automatically and doesn’t require extra code to create a popup box.

Added interactivity as part of the heatmap generated using density_mapbox from plotly express . Image by the author.
Added interactivity as part of the heatmap generated using density_mapbox from plotly express . Image by the author.

Creating a Heatmap with Folium

To begin using Folium, we will need to import it; however, in order to generate heatmaps, we also need to import the HeatMap plugin from folium.plugins.

import folium
from folium.plugins import HeatMap

Once Folium has been imported, we need to create a base map by calling upon folium.map() . Within that class method, we can pass in several arguments. For this example, we will use the following:

  • location – The position where the map will be centred upon
  • zoom_start – The initial zoom level of the map
  • control_scale – Whether the scale controls are displayed on the map

If you want to find out more about the parameters for the map function, then check out the help documentation on the folium.map class.

m = folium.Map(location=[df_combined.Latitude.mean(), 
                         df_combined.Longitude.mean()], 
               zoom_start=6, control_scale=True)

We next need to create the heatmap layer.

To do this, we first need to convert the latitude, longitude and values to a list, which can then be passed into the HeatMap call.

We can set a few parameters to stylise how the heatmap appears, such as the min and max opacity, the radius of the colouring from the data point, and more.

map_values = df_combined[['Latitude','Longitude','DTC']]

data = map_values.values.tolist()

hm = HeatMap(data,
              min_opacity=0.05, 
              max_opacity=0.9, 
              radius=25).add_to(m)

When we call upon our map object, we can see a similar pattern to the one generated by plotly express.

Heatmap generated using Folium. Image by the author.
Heatmap generated using Folium. Image by the author.

However, there are a couple of downsides to this map:

There is no hover functionality similar to what we saw above with Plotly Express. We could add markers, but it requires several lines of additional code.

If you want to see how to do this, check out my article below.

Folium Mapping: Displaying Markers on a Map

The other issue is that there is no colour gradient bar to help readers understand the range of colours. But this can be resolved by creating a colour map dictionary, as discussed in the following StackOverflow post.

How to add legend/gradient in Folium Heat Map?

Conclusions

Heatmaps provide a great way to visualise and identify trends across geographical areas and can easily be created using two popular Python libraries: Folium and Plotly Express. These two libraries are simple to use and can be used to map petrophysical and well-log properties across large regions. From these maps, we can derive information about trends and variations across fields or areas.


Thanks for reading. Before you go, you should definitely subscribe to my content and get my articles in your inbox. You can do that here! Alternatively, you can sign up for my newsletter to get additional content straight into your inbox for free.

Secondly, you can get the full Medium experience and support me and thousands of other writers by signing up for a membership. It only costs you $5 a month, and you have full access to all of the amazing Medium articles, as well as the chance to make money with your writing. If you sign up using my link, you will support me directly with a portion of your fee, and it won’t cost you more. If you do so, thank you so much for your support!

Data Sets Used in this Tutorial

The dataset used for this tutorial is composed of two other datasets:

  1. A subset of a training dataset used as part of a Machine Learning competition run by Xeek and FORCE 2020 (Bormann et al., 2020). The full dataset can be accessed at the following link: https://doi.org/10.5281/zenodo.4351155.

  2. Well Location Data from the Norwegian Petroleum Directorate website Data can be downloaded here: https://factpages.npd.no/en/wellbore/tableview/exploration/all

Both datasets are licensed under a NOLD 2.0 licence from the Norwegian Government, details of which can be found here: Norwegian Licence for Open Government Data (NLOD) 2.0.


Towards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.

Write for TDS

Related Articles