Making an Interactive Web Map in Python with Folium: Part 1 — Preparing the Data
By: Noah Christiansen
Tags: Data Science, Python, Geopandas, Mapping, Folium

As a lover of maps, cartography, geography, and all things spatial, I’d be the first to advocate for the use of maps when visualizing any information that has a spatial component. Maps are able to convey a great deal of information in an understandable, intuitive, and digestible form, all while often remaining aesthetically pleasing (usually without much of a need for tweaking style parameters). Additionally, maps have the unique capacity to let readers find themselves in the data being shown, to situate themselves in the story being told. For this reason, when I work on a project, I often try to find a way to visualize the data spatially through either a static map or a dynamic, interactive one.

While much of my experience with map-makery (read: cartography) has been in the creation of static map images, I recently started using Python to make some interactive web maps that allow users to explore the data stored in these maps for themselves. One of the main libraries I’ve been using to make interactive maps has been folium, a Python library that builds on leaflet.js to make it relatively simple to take data in Python and visualize it on a Leaflet map.

Since I recently finished a project trying to predict fire risk for New York City census tracts, I thought I would take my newfound folium skills and apply them to the same dataset of fire incidents. I will walk through the steps necessary to prepare the fire incident dataset for creating an interactive map.

For the first step of this exercise, I import the usual suspects (pandas, numpy, and matplotlib) as well as two libraries that allow for the creation and manipulation of spatial data in Python: geopandas and shapely.

Since I’m mapping the fire incidents, I only need to import the Point module from shapely.

Then I can import the dataset of geocoded fire incidents. This is the version of the fire incident data I used in my project after geocoding each incident. Here I can use pandas to read in the data with the read_csv() method. I also like to use a few pandas methods right away to get a better sense of the data’s structure.

Since there are lat (latitude) and lon (longitude) columns for the data, I can use these to create point geometries for each row in the dataset. Shapely’s Point constructor enables me to do this by passing a tuple of coordinates into Point(). As this needs to be done for every lon-lat pair in the dataset, I can use a list comprehension to create a list of Points that serves as the geometry column. However, in order for the dataframe to become a GeoDataFrame, I need to use geopandas’ GeoDataFrame() method with the incident dataframe as the input data and the list of Points as the geometry. The code for this process looks like this:

The resulting GeoDataFrame functions in much the same way as the pandas dataframe; I can check the columns and missing values with .info(), look at the first few rows with .head(), and even do a simple plot of the data using matplotlib with .plot(). To check that this transformation worked and that the Points data looks the way it should, I can run that last command and look at the resulting plot.

Looks roughly like the five boroughs of New York City, if the city was composed of little blue dots. Excellent, looks like I’m on the right track.

Since this post is getting a bit long, I’m going to save the last steps (making an interactive map with folium using this data) for my next post. I’ll be picking up from where I’m leaving off here, so stay tuned.