Josh Redmond

by Josh Redmond

Lesson

6. Mapping with Ipyleaflet Vectors

After this lesson, you will be able to:

  1. Create leaflet maps and interact with them
  2. Load and interact with geospatial vector data
  3. Add vector data to an interactive leaflet map

We have worked with matplotlib and widgets, and now its time to do some mapping! Using the excellent ipyleaflet we are going to build a basic web map, at first we will just display some data, but we will build up to allowing interaction using the skills you have practiced before. A number of the same ideas, like observers and accessing the attributes of different parts of the map, are important concepts for using ipyleaflet.

In a new Jupyter Notebook, lets start by creating a map. The code below will create a map and add a marker to the map that the user can drag around - try for yourself:

#First, lets create a map and marker:
import ipyleaflet
from ipyleaflet import Map, Marker, ImageOverlay

center = (53.8008, -1.5491)

m = Map(center=center, zoom=10)

marker = Marker(location=center, draggable=True)
m.add_layer(marker)

display(m)

And there we have it - a map! One of the interesting things about ipyleaflet is that it uses the same widget based approach we have seen earlier, so all the interactable objects and markers can be set up with observers, callbacks, and so on. This lets you build a lot of functionality from a user's point of view, and can let you create quite advanced features. For example, loading in new data depending on the map's view extent, allowing interaction with objects drawn to the map by clicking on them, and so on.

Ipyleaflet is a Python wrapper for the JavaScript library Leaflet. Leaflet is a really popular web-mapping tool, which powers lots of interesting websites and apps. You can see some examples here.

Working interactively with ipyleaflet is a bit different to matplotlib. Where Matplotlib is essentially static, creating images which can be updated, ipyleaflet creates widgets to dispay an interactive map. This means that you don't need to worry so much about resetting and updating the data it displays, you can simply add and remove things from the map, and the map will update automatically. Maps also work with observers and some of the other features we've worked with earlier. Below we are going to use a button to update the data on the map:

import ipywidgets as widgets

reset_button = widgets.Button(description="Reset Marker")

def reset_marker(button):
    marker.location = center
    m.center = center

reset_button.on_click(reset_marker)
display(reset_button)

Ok great- you have created a map and you can add and remove features. Think back to the earlier lessons where we built interactive features using Matplotlib; you can use the same ideas here, but with geographic data, to alter how it is displayed and to change the data itself.

Using geopandas, we can easily load and work with geospatial vector data in a number of formats. You might be familiar with kml, shapefiles, or other file types; in this case we will be working with geojson files. Geopandas can work with a wide variety of different file types very easily, and lets you interact with this data like its a pandas dataframe. This makes things very easy, and you can add these dataframes straight to your map using ipyleaflet's geodata functions. We're going to load in some census data from Leeds, which contains the geometries of the census output areas, along with data about the population. This data is in the geojson format.

from ipyleaflet import GeoData
import geopandas as gpd

vector_data = gpd.read_file('leeds_census.geojson')
vector_layer = GeoData(geo_dataframe = vector_data)
m.add_layer(vector_layer)
m

Much in the same way we can add and update data to our matplotlib charts from earlier, we can do the same with these maps. For example:

change_colour_button = widgets.Button(description="Change Map Colour")

def change_colour(button):
    vector_layer.style = {'color': 'black', 'fillColor': 'blue'}
    
    
change_colour_button.on_click(change_colour)
display(change_colour_button)

You can also vary the display of the vectors on the map depending on their attributes. Lets take a closer look at that geodataframe we have created:

vector_data.head()

You can see that a geodataframe, much like a standard pandas dataframe, contains columns and rows of data, with an extra column containing the geometry or spatial information for each feature. This means that its really easy to add new data to the frame, in the exact same way that you might do so with a pandas dataframe.

vector_data['population times ten'] = vector_data['Population'] * 10 

Similarly - you can save and update the file that you have been working with very easily, with the slightly added complexity of having to designate which format you want to use as there are a large number of different options for geospatial data. We'll save it here again as a geojson.

vector_data.to_file("leeds_census_update.geojson", driver="GeoJSON")

When you are plotting vector data, the chances are that you want to display some kind of quantitative or qualitative information, not just the geometries. In ipyleaflet there are a few different ways to do this, the approach we will use is the Chloropleth layer, which uses slightly different data management than the geodata layer. This visualisation tool works with json data directly, rather than with a dataframe. Luckily, geopandas has an easy way of getting a json string from a geodataframe.

geojson_dict = vector_data.__geo_interface__

We now need to create a dictionary to tell ipyleaflet what features to give what values, and use a colour map to transform these values into colours.

from branca.colormap import linear

population = dict(zip(list(vector_data.index.map(str)), list(vector_data['Population'])))

chloro_layer = ipyleaflet.Choropleth(
    geo_data=json_dict,
    choro_data=population,
    colormap=linear.YlOrRd_04)
    
m.add_layer(chloro_layer)
m
    
m.add_layer(chloro_layer)

m

In contrast to the geodata layer, where you are easily able to vary the visualisation parameters when you create the layer, the chloropleth visualisation parameters are linked to the data itself. Both of these layers can serve different purposes for mapping, and its good to be aware of how both of them work.

In the next lesson, we will learn similar approaches for working with raster (image or gridded) data in ipyleaflet, including how to generate that data and vary parameters interactively.