Maps and Cartography

This build demonstrates how to use Jupyter notebooks to work with geographical objects and create and display a wide range of maps, from static, publication quality maps to interactive web based maps.

See here (docs) for an example of the OpenGeoscience/geonotebook package which provides a more elaborate environment for working with geo-data in a notebook context.

For examples of astronomical maps, see the showntell/astronomy branch.

To display all the generated cell output, from the noteboon Cell menu, select Run All.

The notebook may contain code cells with hidden inputs (that is, hidden code). To see the hidden input for a given cell, select the cell and click on the Toggle selected cell input dissplay button on the toolbar. To hide/reveal all code, toggle the Hide/Show codecell inputs button.

Working with Geo-Data

Interactive Maps

Jupyter notebooks provide a natural home for embedded, interactive maps.

A wide range of Python packages exist that support the creation and embedding of interactive maps built from third party mapping services such as Google Maps, Bing Maps, and OpenStreetMap (OSM).

Packages can also work with tiles served from a personally hosted map tile server.

ipyleaflet

The ipyleaflet package supports the creation of embedded, interactive maps using the leaflet.js Javascript package.

In [9]:
import ipyleaflet as lflt

m = lflt.Map(center=[52.0250, -0.7084], zoom=14)
m

folium

The folium package supports the creation and embedding of interactive maps from ...

Simple Maps

In [10]:
import folium


m = folium.Map(location=[52.0250, -0.7084], zoom_start=14)
m
Out[10]:

To try to simplify embedding maps, we can create some magic to load a map based on location, provided as latitude / longitude co-ordinates. (If no latitude and longitude values are provided, a default value is used.)

In [11]:
%load_ext folium_magic 
The folium_magic extension is already loaded. To reload it, use:
  %reload_ext folium_magic
In [12]:
%folium_map -l 52.0250,-0.7084
Out[12]:

Adding Markers

In [13]:
m = folium.Map(location=[52.0250, -0.7084], zoom_start=14, tiles='Stamen Toner')

folium.Marker([52.0250, -0.7084],
              popup='Open University, Walton Hall').add_to(m)
m
Out[13]:

The magic can be extended to allow for the inclusion of a marker:

In [14]:
%folium_map -m 52.0250,-0.7084,"My marker" -z 12
Out[14]:

We can also add sets of markers, provided in a variety of ways.

In [43]:
#We can accept all the following variants to get a marker in a map
markers={'lat':52.0250, 'lng':-0.7084,'popup':'Open University, Walton Hall'}
markers=[[52.0250, -0.7084,'Open University, Walton Hall'], [52., -0.7,'Open University, Walton Hall']]
markers=[52.0250, -0.7084,'Open University, Walton Hall']
markers=[{'lat':52.0250, 'lng':-0.7084,'popup':'Open University, Walton Hall'},
        {'lat':52.0, 'lng':-0.70,'popup':'Open University, Walton Hall'}]
In [44]:
%folium_map  -M markers
Out[44]:

Adding Boundaries to Maps

Boundaries represented using a .geojson file can be rendered as an overlayed map layer.

In [17]:
import os
m = folium.Map( location=[52.0250, -0.7084], zoom_start=9 )

#Path to geojson file
mk = os.path.join('boundaries', 'mk.json')

#Add geojson layer to map
folium.GeoJson( mk, name='geojson' ).add_to(m)

m
Out[17]:

The magic can also accept the path to a geoJSON file. If no latitude and longitude are selected, the centroid of the area will be used.

In [18]:
%folium_map -g boundaries/mk.json
Out[18]:

Choropleth Maps

In [19]:
import pandas as pd
turnout=pd.read_csv('data/iw_turnout.csv')
turnout.head()
Out[19]:
Electoral Division Candidate Electorate NoOnRoll turnout
0 Arreton and Newchurch Total votes cast 1286 3070 0.418893
1 Binstead and Fishbourne Total votes cast 1160 2766 0.419378
2 Brading, St Helens and Bembridge Total votes cast 4640 6189 0.749717
3 Carisbrooke Total votes cast 883 2632 0.335486
4 Central Wight Total votes cast 1339 2904 0.461088
In [20]:
import fiona

with fiona.open('boundaries/iw.json') as fi:
    latlong=[(fi.bounds[1]+fi.bounds[3])/2,
             (fi.bounds[0]+fi.bounds[2])/2]

m = folium.Map(location=latlong )

m.choropleth(
   geo_data='boundaries/iw.json',
    data=turnout,
    columns=['Electoral Division', 'turnout'],
    key_on='feature.properties.WD13NM',
    fill_color='PuBuGn', fill_opacity=0.7
)

m
Out[20]:

The magic can also plot chorpleths. The data to be used can be passed in by reference to the name of a variable containing the data to be plotted.

In [21]:
%folium_map -g boundaries/iw.json -d turnout -c 'Electoral Division','turnout' -k feature.properties.WD13NM
Out[21]:

Or we can pass the path to a data file containig the data.

In [22]:
%folium_map -g boundaries/iw.json -d data/iw_turnout.csv -c 'Electoral Division','turnout' -k feature.properties.WD13NM
Out[22]: