Interactive Mapmaking with Python

Sangarshanan

Data + Pandas <3

In [1]:
import pandas
df = pandas.read_csv('data/cities.csv')
df.head()
Out[1]:
name longitude latitude
0 Vatican City 12.453387 41.903282
1 San Marino 12.441770 43.936096
2 Vaduz 9.516669 47.133724
3 Luxembourg 6.130003 49.611660
4 Palikir 158.149974 6.916644

Data with a location component

Geometries

  • Point (latitude, longitude)
  • Polygon [point1, point2]

We can also have linestrings, multipolygons, circles etc

Enter GeoPandas

  • Work with a Familiar interface (Dataframes), in this case Geodataframes
  • Read/ write GIS data (Fiona) formats like shapefile, geojson, kml etc
  • Perform spatial operations like merge/join/overlay etc (Shapely)
  • Plot em on a map (Matplotlib)

Also a whole lot of other things like handling projections, recently added vectorized geometrical operations, Indexing with rtree... and more such goodies

Interested in more, https://github.com/jorisvandenbossche/geopandas-tutorial has a comprehensive tutorial by the maintainer

In [2]:
df.head()
Out[2]:
name longitude latitude
0 Vatican City 12.453387 41.903282
1 San Marino 12.441770 43.936096
2 Vaduz 9.516669 47.133724
3 Luxembourg 6.130003 49.611660
4 Palikir 158.149974 6.916644
In [3]:
import geopandas
# Converting latitude, longitude to geometry object
gdf = geopandas.GeoDataFrame(
    df, geometry=geopandas.points_from_xy(df.longitude, df.latitude))
# setting the projection
gdf.crs = 'epsg:4326'
gdf.head()
Out[3]:
name longitude latitude geometry
0 Vatican City 12.453387 41.903282 POINT (12.45339 41.90328)
1 San Marino 12.441770 43.936096 POINT (12.44177 43.93610)
2 Vaduz 9.516669 47.133724 POINT (9.51667 47.13372)
3 Luxembourg 6.130003 49.611660 POINT (6.13000 49.61166)
4 Palikir 158.149974 6.916644 POINT (158.14997 6.91664)

How do I plot em ?

With geopandas, its as simple as .plot()

In [29]:
import matplotlib.pyplot as plt
gdf.plot()
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f07cabfb710>

Italian Trulli

Italian Trulli

Folium Plots

In [5]:
gdf.head(1)
Out[5]:
name longitude latitude geometry
0 Vatican City 12.453387 41.903282 POINT (12.45339 41.90328)
In [6]:
# import the library
import folium
# Create a map with a center and zoom level
mapa = folium.Map(location= [-15.783333, -47.866667],
                  zoom_start= 1,
                  tiles= "OpenStreetMap")
mapa
Out[6]:
In [7]:
# Add the geodataframe as a geojson feature
points = folium.features.GeoJson(gdf, 
                                 # tooltip with the name
                                tooltip=folium.GeoJsonTooltip(fields=['name']))
# Adding the feature to the canvas we created
mapa.add_child(points)
mapa
Out[7]:

Onward to Polygons

In [8]:
world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
world.head(2)
Out[8]:
pop_est continent name iso_a3 gdp_md_est geometry
0 920938 Oceania Fiji FJI 8374.0 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 53950935 Africa Tanzania TZA 150600.0 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
In [9]:
#https://matplotlib.org/3.1.1/gallery/color/colormap_reference.html
world.plot(figsize=(20,5), column= 'gdp_md_est', cmap='YlGnBu', legend=True)
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f07d3faecc0>
In [10]:
import branca.colormap as cm
colormap = cm.linear.YlGnBu_09.to_step(data=world['gdp_md_est'], n=9)
colormap
Out[10]:
16.021140000.0
In [11]:
m = folium.Map()
# Setting the style
style_function = lambda x: {
    # How to fill color of the polygon
    'fillColor': colormap(x['properties']['gdp_md_est']),
    # Color of Polygon
    'color': 'black',
    # Weight of the border (Around the Polygon)
    'weight': 0.5,
    # Opacity of filled color
    'fillOpacity': 0.75
}
In [12]:
# Creating a geojson map with the style
folium.GeoJson(
    world,
    tooltip=folium.GeoJsonTooltip(fields= ["name", "gdp_md_est"]),
    style_function=style_function
).add_to(m)
# Add the legend to the same canvas
colormap.add_to(m)
m
Out[12]: