Wenyan Deng
Ph.D. Candidate
Massachusetts Institute of Technology
Folium: Interactive Maps
July 21, 2017
The case study
In last time's blog, we saw how to make a static choropleth map. This time, I overlay the choropleth map on an interactive platform using folium. See a copy of the final product in my GitHub repository. The final product of this project is shown in Figure 1.
Figure 1: Interactive map with Folium
Getting started
Open a jupyter notebook and import the following:
%matplotlib inline
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
Load the geo-dataframe and rename the column so it makes sense at a glance:
geo_df = gpd.read_file("data1/LKA_adm1.shp")
geo_df.rename(columns = {"NAME_1" : "Districts"}, inplace = True)
geo_df.head()
Load the deaths dataframe created last time from the spatial join function:
deaths_geo_count = pd.read_excel("deaths_geo_count.xlsx")
Merge the deaths dataframe and the geo-dataframe by districts:
geo_merge = geo_df.merge(deaths_geo_count, on='Districts', how='left')
col_name =geo_merge.columns[0]
geo_merge.head()
Mapping
Import folium:
import folium
from folium.element import IFrame
from geopy.geocoders import Nominatim
Get the folium base map and set zoom position, then start mapping.
m = folium.Map([8, 79.8], tiles='cartodbpositron', zoom_start=8)
ft = "deaths_per_district"
cmap = folium.colormap.linear.YlOrRd.scale(geo_merge[ft].min(), geo_merge[ft].max())
folium.GeoJson(geo_merge, style_function=lambda feature: {
'fillColor': cmap(feature['properties'][ft]),
'fillOpacity' : 0.7,
'weight' : 1, 'color' : 'black' }).add_to(m)
cmap.caption = 'Deaths by district'
Next, if you want the map to also show the exact locations of deaths, import the original deaths files, which describes the names of the deceased, dates of death, and places of death. Use a "for" loop to add that information to markers as pop-ups.
deaths = pd.read_excel('SLA_RoH_Deng.xlsx')
deaths["DATE"] = deaths["DATE"].astype(str)
deaths["NAME"] = deaths["NAME"].astype(str)
deaths["PLACE"] = deaths["PLACE"].astype(str)
my_marker_cluster = folium.MarkerCluster().add_to(m)
for ix, row in deaths.iterrows():
text = "Name: " + row['NAME'] + "<br>" + "Location: " + str(row['PLACE']) + "<br>" + "Date: " + str(row['DATE'])
popup = folium.Popup(IFrame(text, width=300, height=100))
folium.Marker(location = [row['Latitude'],row['Longitude']], popup=popup).add_to(my_marker_cluster)
Save the map!
m.save("HeatMap.html")
m
You can zoom in and click on each point to view its associated pop-up (see figure below). Happy mapping!