I wanted to create a Choropleth map for some Toronto data I have that is organized by FSA (Forward Sortation Area — the first three digits of the Canadian Postal Code). I’ve mostly been using Folium for creating these kind of maps, which requires a GeoJSON file as an input. Alas, I couldn’t find an existing GeoJSON online for Toronto FSAs and realized that I would need to generate one. That lead me down a nasty rabbit hole — I’m sure there is an easier way to accomplish this, but, for the record, these are the steps I followed.
Statistics Canada does publish some Census Boundary Files data for Canadian FSAs (available here) and I found a couple blogs that pointed me in the right direction for how to convert that file to the GeoJSON format (thanks Curtis Pokrant and Chad Skelton)
- On the StatsCan website, set the format to ArcGIS ® (.shp) file, select the
Digital Boundary File for Forward Sortation Area and click Continue to download
- This will download a zip file with a bunch of components. The important one is the .shp file
- We can use QGis to do convert the .shp file to GeoJSON (it’s a free download)
- YKCZoli has an excellent tutorial on how to do this here, so I won’t repeat everything
- First, select Layer… Add Layer… Add Vector Layer and find the .shp file
- This will load data for all of Canada, but we want to narrow it down to just Ontario
- Select Layer… Filter
- In the Fields section, double-click on PRNAME to add it to the Filter Selection box
- Click the “All” button under values and when the provinces are loaded, double-click on Ontario to add it to the Filter Selection box
- You should end up with a query that looks like
"PRNAME" = 'Ontario'
- Spoiler alert… if you just narrow down the selection to Ontario, the resulting GeoJSON file is still going to be fairly large (~16MB) and the Folium Choropleth map will not render (it won’t error out but will just give you a blank display). I spent a bit of time banging my head on this one until I realized that the json file was still too big. We have two choices — we can narrow it down further to particular FSAs or we can find a way to simplify the .shp file. I was only interested in creating a map for Toronto, so I went the first route
- I added an extra filter on for CFSAUID (FSA) and pasted in all my FSAs
- To save this file in GeoJSON format, choose Layer… Save As
- Set the format to “ EPSG: 4326.” and choose where to save the file
- Verify that the result file isn’t too large
To test it out, let’s map population in Toronto FSAs using Folium and Python. First we’ll load our libraries
import folium # map rendering library
import numpy as np
import pandas as pd
Next, read in Canada Census population data from 2016 and filter for our columns and rows of interest (Population, 2016 for Ontario)
df_pop = pd.read_csv("./data/T1201EN.CSV")
# we can immediately drop the columns we're not interested in
df_pop=df_pop[['Geographic code','Province or territory', 'Population, 2016']]
df_pop=df_pop[(df_pop['Province or territory']== "Ontario")]
Now create our map
- if you end up with a blank display, it could be that your json file is still too large and needs to be further filtered or simplified
- The FSA is stored in the key feature.properties.CFSAUID
map_toronto = folium.Map(location=[43.653963, -79.387207], zoom_start=10)
ontario_geo = "./data/Toronto2.geojson"
data = df_pop,
columns=['Geographic code','Population, 2016'],
legend_name='Population by FSA')
And, at last… A map of Toronto FSAs!
The python code for this chart can be found here.