What is a GeoJSON File? And Can we Jerry Rig One with Python?

I’m a big believer of learning by disassembly and reassembly, so for today’s walk-through, we’re going to break open a GeoJSON file to see what falls out.

Go to Mapbox’s Guide for Choropleth Maps, and download the GeoJSON data. I’m warning you right now, it’s gross. Here’s a screenshot of what that looks like opened in Notepad.

It is magical though. Leaflet’s site attributes the GeoJSON state shapes to Mike Bostock, whose website is friggin’ delightful. The file on Leaflet was extended to include census density values associated with each state.

How Did They Do That?

JSON is just a collection of key, value pairs in curly brackets. It’s typically {“Some Category”:”Data”}, but the data can be HEAVILY nested, which is unpleasant. (There’s a longer discussion on that over at JSON: How to Read Your Google Location Data if you’re curious.)

GeoJSON is just JSON with key value pairs laid out in a very particular way. If laid out as a FeatureCollection, you can define a s*** load of shapes along with properties that’ll determine how they’re displayed on the map. Those shapes can be points, lines, polygons—or collections of those, like multi point, multiline, and multipolygons.

Take a look at this breakdown of the stateData GeoJSON file pieced apart into its Feature Array and Nested JSON objects for Feature Properties and Geometry.

When formatted, it’s a little easier to see each part—first the state name, the density, and then the coordinates of the state’s boundaries. The vast majority of data in the GeoJSON file is coordinates because states have complicated boundaries.

So What If I Wanted to Jerry Rig My Own JSON Data Based on That One?

So we have state coordinates, what if we pushed a different state property into the GeoJSON file?

For the new state property part, I turned to Wikipedia. Lots of data. Conveniently broken down by state. To start off, why don’t we try making a map showing the number of films set in specific states?

Step 1: Create a Data Dictionary

A quick disclaimer before we continue. There’s probably a way to script this part, but I do not script things that I can do just as easily in Excel. I literally copied and pasted over the text from Wikipedia, worked some Find/Replace, and then Text to Columns to split everything up. I got rid of subcategories and only noted the number of pages associated with each state.

To format a data dictionary in Excel, I put keys in column A and items in column B, then assemble by concatenating those cells with quotation marks around any strings, a colon in the middle, and a comma at the end. Yes, in case you’re wondering, Excel does require 4 quotation marks to put a single quotation mark into a cell as a string.

Then I copy the column with the formula and paste special (values only) to capture the dictionary as hard-coded strings. That’s what I pasted into Jupyter notebooks.

Step 2: Insert the Film Data Using the States as Dictionary Keys

Prior to starting this up, you’ll need to save that state GeoJSON file from above to a .json file on your computer. The Python we’ll use here isn’t too complicated. The only module I’m importing is JSON, and that’s only to load the data and then dump it into a new file afterwards. Here’s the breakdown:

You might notice the meat of the Python here is a For Loop that takes us through each state in the JSON file (data[‘features’]). If the loop encounters a state that is also available in the film_total dictionary, it adds the associated value. If not, it sets the film key to 0.

Then it dumps the new JSON into a file called GeoJSON.json in your current directory.

Step 3: Reformat Your GeoJSON

For this next step you’re going to want to install Sublime if you haven’t already. Then open the GeoJSON.json file the Python script created.

To the top, add var statesData = { “type”:”FeatureCollection”, “features”: before your massive list of features, and add a } to the end of the entire line of text to indicate the whole thing is encompassed within that statesData variable.

Use Control+Shift+P to open the Command Palette in Sublime. Then search for Pretty JSON and install it. Then hit Control+Shift+P to open the command palette again and type in pretty JSON to see your options. One should be Format JSON. Click that.

Then you’re going to save this entire file with a .js extension. I called mine statesData.js. This will be important in how you connect it back to your HTML.

Step 4: Plug it into your HTML File

We talked about how to set up your HTML file a while back in Javascript: How to Make a Simple Web Map. The HTML here is going to have the exact same building blocks, but we’re going to adjust a few lines in the core functions that’ll help us add the film data to the map.

A quick refresher on the building blocks:

To make a choropleth map showing the film data, we’re going to do a few key things.

First, we’re going to pull in our javascript file into the HTML using a script tag. If you save your javascript file in the same folder as your index.html file, you can simply reference it by name.

Second, we’re going to steal a couple of really important functions from Leaflet’s Interactive Choropleth Map walkthrough.

The getColor function associates ranges of numbers with hex codes (specifying colors). Our ranges need to go from 16 (Delaware) to 801 (California). I opted for this breakdown.

function getColor(d) {
return d > 800 ? '#800026' :
d > 400 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 80 ? '#FD8D3C' :
d > 50 ? '#FEB24C' :
d > 10 ? '#FED976' :

The style function is going to be important for pulling in the right property to map—in this case, films.

function style(feature) {
return {
fillColor: getColor(feature.properties.films),
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7

Then, you can pull it all together by calling the geoJSON, with its variable name statesData, and add it to the map.

L.geoJson(statesData, {style: style}).addTo(map);

This is what it’ll look like with all that integrated.

And then presto. If you open your html in a browser, you should see this:

More to come later.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: