IpyLeaflet: Interactive mapping in Jupyter notebook | by Abdishakur | Towards Data Science

Interactive maps are an essential part of Exploratory Data Analysis (EDA). In this tutorial, we introduce to you IpyLeaflet Python library, which enables interactive geospatial data visualization in Jupyter Notebook. IpyLeaflet is a bridge between the worlds of Jupyter notebooks and the popular Leaflet Visualization library.
We start with the basics of markers, icons and base maps, followed by a section on how you can integrate Geopandas and IpyLeaflet to visualize the different type of maps — Choropleth and Clustered Points. In the last section, we learn how you can control maps interactively with IpyLeaflet — Search bar and Fullscreen.
We import Ipyleaflet methods that we will use in this tutorial.
from ipyleaflet import (Map, GeoData, basemaps, WidgetControl, GeoJSON, LayersControl, Icon, Marker,basemap_to_tiles, Choropleth, MarkerCluster, Heatmap,SearchControl,  FullScreenControl)from ipywidgets import Text, HTMLfrom branca.colormap import linearimport geopandas as gpdimport json
We also read the data for this tutorial, using Geopandas. The first dataset is the world countries (Polygon). We have also Points dataset from The Armed Conflict Location & Event Data Project (ACLED), where all conflicts around the world are recorded. Note that we read only a subset of the data, conflicts in Africa.
# Countriescountries = gpd.read_file(gpd.datasets.get_path(‘naturalearth_lowres’))# Conflict Dataset Pointsafrica_acled = gpd.read_file( “data/acled2019.shp”, mask = countries[countries[“continent”] == “Africa”])africa_acled.head()
Base maps provide ready-made tiles to give the context in mapping geospatial data. You need to specify the centre point of your map as well as the zoom level, to get a base map for any place in the world.
Here, we call the Map function in IpyLeaflet and pass the base map. The map above uses Esri World Imagery. There are many free base maps available in IpyLeaflet. For example, if We want to change the base map, we can simply reconstruct the map providing a different base map. Or more conveniently, we can update by adding over the map above(add_layer()).
stamen = basemap_to_tiles(basemaps.Stamen.Toner)m.add_layer(stamen)
In the above code, we have changed the base map. Instead of the Esri World imagery, we are now using Stamen Toner base map, as you can see from the base map below.
Basemaps are only useful thus far. You usually want to have your data on top of base maps. We start with the simplest example. Let us say we want to add a point marker at the centre of our map. We can use Marke() method in IpyLeaflet.
marker = Marker(location=center, draggable=False)m.add_layer(marker);m
And now we have a marker inside our base map.
You can customize the markers by providing a custom image as an Icon. We grab here an icon from the Icons Archive website and use as a marker in our map.
icon_url = “http://icons.iconarchive.com/icons/pelfusion/long-shadow-media/512/Maps-Pin-Place-icon.png"icon = Icon(icon_url=icon_url)mark = Marker(location=[57.719503, 12.008843], icon=icon, rotation_angle=0, rotation_origin=’128px 128px’)m.add_layer(mark);m
We have now a second marker in the map, this time the Marker is an icon we have provided. We move to get into using real-world data and plotting interactive maps with IpyLeaflet in Jupyter Notebooks.
Now that we did the basics, we can bring out the data we have read earlier with Geopandas. We start by plotting a simple and interactive map of all countries in Africa. We first limit the polygons to African countries. To create a map with Data, IpyLeaflet accepts Geojson file or Geopandas datagram. Here we construct a Geodata for the countries in Africa. And Finally, we add geodata to the map.
center = [4.546647, 22.373178]zoom = 2africa = countries[countries[“continent”] == “Africa”]africaMap = Map(basemap=basemaps.CartoDB.Positron, center=center, zoom=zoom)# Create a geodatageodata = GeoData(geo_dataframe = africa,  style={‘color’: ‘black’, ‘fillColor’: ‘#E0D071’, ‘opacity’:0.03, ‘weight’:1.9, ‘dashArray’:’2', ‘fillOpacity’:0.6}, hover_style={‘fillColor’: ‘#b08a3e’ , ‘fillOpacity’: 0.8}, name = ‘Countries’)# Add the map to the dataafricaMap.add_layer(geodata)africaMap
This is a barebones interactive map of all countries in Africa. We will develop this further to include hovering and other interactive features later, but for now, this is our interactive map.
Let us add some context. We will add the names of the countries, their population and GDP estimates once we hover on a country. Here we are using IpyWidgets.
html = HTML(‘’’Hover Over Countries’’’)html.layout.margin = ‘0px 20px 20px 20px’control = WidgetControl(widget=html, position=’topright’)africaMap.add_control(control)def update_html(feature, **kwargs):     html.value = ‘’’     <h3><b>{}</b></h3>     <h4>GDP: {:.2e} people</h4>      <h4>Population: {}</h4>      ‘’’.format(feature[‘properties’][‘name’],        feature[‘properties’][‘gdp_md_est’],        feature[‘properties’][‘pop_est’])geodata.on_hover(update_html)
And now, we have a hovering functionality in our interactive map (See the GIF below — Top Right).
Creating a choropleth map with IpyLeaflet requires setting up the data as GeoJSON. Although this is an extra step and we need to store the Geodataframe locally as Geojson. Let us do that first before we set up the Choropleth Map data.
pop = dict(zip(africa[‘name’].tolist(), africa[‘pop_est’].tolist()))africa[[“name”, “geometry”]].to_file(“data/africa.json”, driver=”GeoJSON”, encoding=’utf-8')geojson_data = json.load(open(“data/africa.json”,’r’))for feature in geojson_data[‘features’]:     properties = feature[‘properties’]     feature.update(id=properties[‘name’])     #print(feature[‘id’])
Now, we can set up the choropleth map data using the Geojson data we created above(Note that we have not normalized the data before plotting the choropleth map, We should have done that).
choroplethData = Choropleth(     geo_data=geojson_data,     choro_data=pop,     colormap=linear.YlOrRd_04,     style={‘fillOpacity’: 0.8, ‘dashArray’: ‘5, 5’})
The conflicts dataset we have read earlier contains many points, and if we plot the data as it is, we end up with a lot of points on the map. One usual way to avoid this is to cluster the points, and you can zoom to certain places if you want to get all points. Let us see how we can create a clustered map with IpyLeaflet.
clusterMap = Map(center=center, zoom=zoom)clusterMap.add_layer(MarkerCluster( markers=[Marker(location=geolocation.coords[0][::-1]) for geolocation in africa_acled.sample(1000).geometry]) )clusterMap
In this last section, we cover two controlling functions — Search bar and Fullscreen zoom.
Let us say we want to zoom in to a location by typing its name and also getting the full-screen map. We will add this functionality with the above map to zoom into conflicts points of a specific area.
search = SearchControl(position=”topleft”,  url=’https://nominatim.openstreetmap.org/search?format=json&q={s}',  zoom=5, property_name=’display_name’, marker=marker )clusterMap.add_control(search)control = FullScreenControl()clusterMap.add_control(control)clusterMap
Have a look at the GIF Below showcasing these two functionalities.
IpyLeaftlet has extensive documentation, and you can delve deep into its advanced functionalities. In this tutorial, we have covered some of the basic map-making features in IpyLeaflet with Jupyter notebooks.
To install IpyLeaflet, you can use either Conda or pip.
conda install -c conda-forge ipyleafletpip install ipyleaflet
If you have JupyterLab, you will also need to install the JupyterLab extension:
jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter-leaflet
The code of this tutorial is available in this Github Repository: