Two Great Python Options for Visualising Geospatial Variation
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.
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:
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
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 datalat
— the name for the latitude columnlon
— the name for the longitude columnz
— the name of the column containing the data we want to visualise on the heatmapcenter
— the position where the map will be centred upon. We can call upon the mean of the latitude and longitude columnszoom
— 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.
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.
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 uponzoom_start
— The initial zoom level of the mapcontrol_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.
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.
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.
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.