Creating Maps with Plenario

There is a lot of event data on the City of Chicago Data portal. Geo-visualizations can help to make sense of this data. But to create an interesting map, you first have to aggregate and filter the data into a format you can use. Plenario has some useful API’s to help with that. I decided to try them out while taking a look at the spatial variation of where the city fills in potholes. The results can be found as an interactive map here. All code was done in Python with the help of the Javascript library Leaflet to display the map.

There are over 31,000 potholes that have been filled in the city since the start of this year. Simply mapping each filled pothole as a point on the map would result in too many points to easily see patterns. That’s why I decided to create a choropleth map or heat map to visualize the difference in potholes filled by Census Tracts across the city.

The first step in formatting the data for our map is to spatially aggregate the event data into geographical boundaries. There are different options available for boundaries: Community Areas, Zip Codes, Census Tracts. A complete list can be found by doing a get request on the Plenario API. Here’s what that would look like in Python:

import requests
shapes = requests.get(“")

I choose Census Tracts since they fit well into Chicago borders and are easy to get additional information about from the Census (which I use later).

Now if we have a dataset in mind, like the 311 Service Requests — Pot Holes Reported dataset, we can use the Plenario Spatial Aggregation API to get the count of the potholes for each geographic unit we chose above. We can choose between returning the results in a geojson format or a csv format, but since we will later be visualizing these results, let’s choose the default geojson.

It would be more interesting to see only the potholes that have actually been filled since the start of this year. We can use the Time Filtering API and the Attribute Filtering API to accomplish this task. The request to get aggregate potholes which have been marked as “Completed” from the beginning of the current year until the present day would looks like this:

import datetime
# generate dynamic date times
year_begin = str( + "-01-01"
current_date = str( + "-" + str( + "-" + str(
potholes = “" + year_begin + “&obs_date__le=” + current_date + ‘&311_service_requests_pot_holes_reported__filter={“op”:”eq”, “col”:”status”, “val”:”Completed”}’

That’s enough information that if we now saved the results into a file, we could start creating our map. But, since what we actually are interested in is the relative density of fixed potholes across the city, we should normalize by population to display potholes_filled_per_resident. The census has an API we can call to get this information by Census Tract. We call this API and then merge it with the geojson created above matching by Census Tract Number. The code to create this merged geojson file can be found in its entirety here.

Now that we’ve saved the resulting geojson as a file — we can begin to visualize it. I used the Javascript library Leaflet to create the interactive map in an HTML file. In particular, Leaflet has a tutorial on interactive choropleth maps where it was only necessary to make a few changes.

The Leaflet sample code modifies a single div element of the HTML with our data to display the map. We reference the data of our geojson created in our Python script using Plenario and the Census API as a local variable declared within the script portion of our HTML.

var mygeojson ={…};

The full sample code for the HTML of the map can be found here. Colors in the legend were chosen using the site ColorBrewer.

We can now load the HTML into a browser and view a map of Potholes Filled per 1000 People by Census Tracts in Chicago! Here’s a link again to the page hosted on GitHub Pages:

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.