|

Folium Mapping: Displaying Markers on a Map

Folium is a powerful Python library that makes it easy to visualise geospatial data. It utilises the power of Leaflet.js, which is a popular and leading JavaScript library that can be used to create interactive maps that can be used across both desktop and mobile platforms.

The library has been designed in a way that makes it easy and simple to use whilst maintaining good performance.

There are many ways data can be displayed on a Folium map, including:

  • Markers (points and circles)
  • Heatmaps
  • Clusters
  • Chloropeth

In this short tutorial, we are going to see how we can display both single and multiple markers on a Folium map.

Displaying Markers in Folium Python Tutorial

Installing Folium

If you don’t already have folium installed you can install it via pip:

pip install folium

or Anaconda:

conda install folium

Importing Folium

The first step is to import the libraries we are going to use.

For this tutorial we will be using pandas to load in the data from a CSV file, and Folium for displaying our data on a map.

import folium
import pandas as pd

Loading Well Position Data from CSV

The data we are using for this example comes from the Norwegian Petroleum Directorate website and contains the locations of all wells that have been drilled on the Norwegian Continental Shelf.

Data can be downloaded here:

https://factpages.npd.no/en/wellbore/tableview/exploration/all

The data is 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.

After downloading the data we will now load it using the pandas function read_csv().

df = pd.read_csv('Data/NPD/wellboreExplorationAll.csv', 
                  usecols=['wlbWellboreName', 'wlbNsDecDeg', 'wlbEwDesDeg', 
                            'wlbPurposePlanned', 'wlbCompletionYear'])

# Renaming columns
df.columns = ['Well Name', 'Purpose', 'Completion Year', 'Latitude', 'Longitude']

When we call upon the dataframe ( df ), we are presented with the following:

We can see that we have 5 columns:

  • Well Name — Name of the Well
  • Purpose — What the purpose was behind drilling the well
  • 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

Display a Blank Folium Map

To display a basic map with Folium we need to call upon folium.map() . Within that class method, we can pass in a number of arguments.

  • 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

There are a number of other parameters we can use. If you want to find out more check out the help documentation on the folium.map class.

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

This returns the following map centred on the location specified above.

Base map generated by folium centred over Norway.
Base folium map centred over Norway.

Adding a Single Marker to a Folium Map

The simplest way we can present data on a map is by using markers.

We can add a single marker to our map by calling upon folium.Marker and passing in the location of the point. In this example, we will display the mean latitude and longitude of our data.

To make it appear on the map, we need to apply the .add_to() function and pass in our map object.

#Add a single marker

folium.Marker(location=[df.Latitude.mean(), df.Longitude.mean()]).add_to(map)

And when we call upon the map object we get the following map, with a marker at the mean location of all data points (centre of the map).

Folium map showing the mean location of all of our wells.

Changing the Colour of the Marker on a Folium Map

We can also change the colour of our markers by calling upon the icon argument within the Marker method and setting it equal to:

folium.Icon(color='red', icon='')

The marker colour can be any of the following:

‘red’, ‘blue’, ‘green’, ‘purple’, ‘orange’, ‘darkred’, ’lightred’, ‘beige’, ‘darkblue’, ‘darkgreen’, ‘cadetblue’, ‘darkpurple’, ‘white’, ‘pink’, ‘lightblue’, ‘lightgreen’, ‘gray’, ‘black’, ‘lightgray’

To remove any symbols within the Folium marker we can set icon equal to a blank string.

Once we have chosen the colour, we then we need to add it to our map by using .add_to(map).

This is what the full code looks like:


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

folium.Marker(location=[df.Latitude.mean(), df.Longitude.mean()], 
              icon=folium.Icon(color='red', icon='')).add_to(map)

Which generates the following map with our marker colour changed to red.

Folium marker after changing the colour and removing the symbol.

Changing the Icon on the Marker on a Folium Map

In the above example, we removed the icon, but if we wanted to use an icon of our own choice we can pass in one of the named symbols from the Bootstrap website below.

https://getbootstrap.com/docs/3.3/components/

As an example, we can set the icon to pushpin

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

folium.Marker(location=[df.Latitude.mean(), df.Longitude.mean()], 
              icon=folium.Icon(color='red', icon='pushpin')).add_to(map)
              
map

Then when we run the code and view the map we can see the icon has been updated to a pushpin.

Folium marker after changing the symbol.

When we zoom in, we can have a clearer view of what the icon looks like.

Zoomed in view of our marker and selected symbol.

Adding Multiple Markers to a Folium Map

We could continue adding markers one by one, which may be fine for a small dataset. But when you have a dataset like this one with over 2,000 rows we need to consider an alternative approach.

In the code below:

  • We call upon our map and change the zoom_start to 3, which will zoom the map out more than the previous maps
  • We then iterate over each row in the dataframe
  • We then create an iframe object, which allows us to have more control over the popup appearance and content. In this case we are just displaying the well’s name
  • Next we create the popup and pass the iframe object and dimensions of the popup
  • Finally, we take each row’s Latitude and Longitude and add them to the map

map = folium.Map(location=[df.Latitude.mean(), df.Longitude.mean()], 
                 zoom_start=3, control_scale=True)

#Loop through each row in the dataframe
for i,row in df.iterrows():
    #Setup the content of the popup
    iframe = folium.IFrame('Well Name:' + str(row["Well Name"]))
    
    #Initialise the popup using the iframe
    popup = folium.Popup(iframe, min_width=300, max_width=300)
    
    #Add each row to the map
    folium.Marker(location=[row['Latitude'],row['Longitude']],
                  popup = popup, c=row['Purpose']).add_to(map)

When we run this and call upon our map object, we get the following map back with all of the locations of the offshore Norwegian wells.

Folium map after adding multiple markers.

We can click on any well to see the popup and the name of the well.

Folium popup in an iframe containing the name of the well.

Controlling Folium Marker Colour by Category

Rather than having a single colour representing the Folium markers, we can change the colour depending on a property within our data.

In this example, we will change the colour of our marker based on the purpose of the well.

For this we need to setup a dictionary with the purpose and a related colour. In this case we have three categories: WILDCAT, APPRAISAL and WILDCAT-CCS which are assigned to red, green and blue respectively.

As this column contains a few missing values (nans), we need to setup a short try-except block on line 15 to 19.

To call upon these colours, we change the parameter for the color argument within the call to folium.Icon().


# Set up the colours based on well's purpose
purpose_colour = {'WILDCAT':'red', 'APPRAISAL':'green', 'WILDCAT-CCS':'blue'}

map = folium.Map(location=[df.Latitude.mean(), df.Longitude.mean()], 
                 zoom_start=3, control_scale=True)

#Loop through each row in the dataframe
for i,row in df.iterrows():
    #Setup the content of the popup
    iframe = folium.IFrame(f'Well Name: {str(row["Well Name"])} \n Purpose: {str(row["Purpose"])}')
    
    #Initialise the popup using the iframe
    popup = folium.Popup(iframe, min_width=300, max_width=300)
    
    try:
        icon_color = purpose_colour[row['Purpose']]
    except:
        #Catch nans
        icon_color = 'gray'
    
    #Add each row to the map
    folium.Marker(location=[row['Latitude'],row['Longitude']],
                  popup = popup, 
                  icon=folium.Icon(color=icon_color, icon='')).add_to(map)
    

When we call upon the map, we now have our markers coloured by their purpose.

Folium map with markers coloured by category.

We can zoom in and check a marker to see what the pop says.

Folium map with markers coloured by category and custom popup.

Summary

Folium provides a great platform on which to display geospatial data. It is easy and simple to use once you understand the basics of it. If you have time, it is worth exploring the other map types available within the Folium library.

Similar Posts

Leave a Reply

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