Show Sidebar Hide Sidebar

County Level Choropleth in Python

How to make a Choropleth Map of Florida in Python with Plotly.

New to Plotly?

Plotly's Python library is free and open source! Get started by dowloading the client and reading the primer.
You can set up Plotly to work in online or offline mode, or in jupyter notebooks.
We also have a quick-reference cheatsheet (new!) to help you get started!

Version Check

Run pip install plotly --upgrade to update your Plotly version

In [1]:
import plotly
plotly.__version__
Out[1]:
'2.0.6'

In this tutorial, we will be creating a choropleth of Florida's counties with the Republican and Democratic counties colored red and blue respectively.

Mapbox Access Token

To plot on Mapbox maps with Plotly you'll need a Mapbox account and a Mapbox Access Token which you can add to your Plotly settings. If you're using a Plotly On-Premise server, please see additional instructions here: https://help.plot.ly/mapbox-atlas/.

Read the Data

Read both a GeoJSON file of the Florida counties and a webpage indicating Florida's voting registration by county

In [2]:
import urllib
import ast
import HTMLParser
import string
import json

url = 'http://catalog.civicdashboards.com/dataset/cda82e8b-7a8b-411e-95ba-1200b921c35d/resource/5c5d19a0-b817-49e6-b76e-ea63a8e2c0f6/download/fd880c1e4d23463ca869f1122109b3eftemp.geojson'
florida_data = urllib.urlopen(url).read()
florida_data = ast.literal_eval(florida_data)

repub_democ_counties_url = 'http://dos.myflorida.com/elections/data-statistics/voter-registration-statistics/voter-registration-monthly-reports/voter-registration-current-by-county/'
repub_democ_counties = urllib.urlopen(repub_democ_counties_url).read()

Since we want to separate the counties into Republican and Democratic for the seperate coloring, and since the county names in the GeoJSON are fuller text descriptions of each county on the website, we need to parse through and convert the names in the GeoJSON to the website format

In [3]:
county_names = []
county_names_dict = {}

for county in florida_data['features']:
    for m in range(len(county['properties']['name'])):
        if county['properties']['name'][m:m+6] == 'County':
            county_names.append(county['properties']['name'][0:m-1])
            county_names_dict[county['properties']['name'][0:m-1]] = county['properties']['name']
            
print county_names
['Charlotte', 'Seminole', 'Baker', 'DeSoto', 'Levy', 'Alachua', 'Pasco', 'Hendry', 'Okeechobee', 'Broward', 'St. Johns', 'Gulf', 'Glades', 'Marion', 'Duval', 'Madison', 'Osceola', 'Lee', 'Volusia', 'Sarasota', 'Indian River', 'Clay', 'Putnam', 'Wakulla', 'Holmes', 'Escambia', 'Flagler', 'Union', 'Brevard', 'Suwannee', 'Orange', 'Martin', 'Nassau', 'Jefferson', 'Santa Rosa', 'Hamilton', 'Calhoun', 'Hernando', 'Miami-Dade', 'Pinellas', 'Palm Beach', 'Hillsborough', 'Collier', 'Gilchrist', 'Dixie', 'Bay', 'Gadsden', 'Okaloosa', 'Citrus', 'Lafayette', 'Manatee', 'Monroe', 'Columbia', 'Sumter', 'Washington', 'St. Lucie', 'Polk', 'Taylor', 'Leon', 'Lake', 'Highlands', 'Hardee', 'Bradford', 'Liberty', 'Franklin', 'Walton', 'Jackson']

Color the Counties

We now run a script to color our counties based on political party. This involves parsing through our list of counties, finding their cooresponding Republican/Democratic votes on the website, and place our data into the cooresponding list red_counties or blue_counties, based on which party has more votes

In [4]:
red_counties = []
blue_counties = []

for k, county in enumerate(county_names):
    for j in range(len(repub_democ_counties)):
        county_len = len(county)
        if repub_democ_counties[j:j+county_len] == string.upper(county):
            new_j = j

            while True:
                try:
                    int(repub_democ_counties[new_j])
                    break
                except ValueError:
                    new_j += 1

    repub_votes = ''
    while repub_democ_counties[new_j] != '<':
        if repub_democ_counties[new_j] != ',':
            repub_votes += repub_democ_counties[new_j]
        new_j += 1
    
    # advance to next set of numbers
    new_j += 11

    democ_votes = ''
    while repub_democ_counties[new_j] != '<':
        if repub_democ_counties[new_j] != ',':
            democ_votes += repub_democ_counties[new_j]
        new_j += 1

    repub_votes = int(repub_votes)
    democ_votes = int(democ_votes)

    if repub_votes >= democ_votes:
        red_counties.append(florida_data['features'][k])
    else:
        blue_counties.append(florida_data['features'][k])

Create JSON Files

In plotly/datasets, you can find the generated JSON files below for the red counties and blue counties

In [5]:
red_data = {"type": "FeatureCollection"}
red_data['features'] = red_counties

blue_data = {"type": "FeatureCollection"}
blue_data['features'] = blue_counties

with open('florida-red-data.json', 'w') as f:
    f.write(json.dumps(red_data))
with open('florida-blue-data.json', 'w') as f:
    f.write(json.dumps(blue_data))

and we can now plot our choropleth using Python. Make sure to have a Mapbox Access Tolken for the generation of the plot. For more information on plotting Mapbox maps in Python, checkout the documentation

In [6]:
import plotly.plotly as py
import plotly.graph_objs as graph_objs

mapbox_access_token = "ADD_YOUR_TOKEN_HERE"

data = graph_objs.Data([
    graph_objs.Scattermapbox(
        lat=['45.5017'],
        lon=['-73.5673'],
        mode='markers',
    )
])
layout = graph_objs.Layout(
    height=600,
    autosize=True,
    hovermode='closest',
    mapbox=dict(
        layers=[
            dict(
                sourcetype = 'geojson',
                source = 'https://raw.githubusercontent.com/plotly/datasets/master/florida-red-data.json',
                type = 'fill',
                color = 'rgba(163,22,19,0.8)'
            ),
            dict(
                sourcetype = 'geojson',
                source = 'https://raw.githubusercontent.com/plotly/datasets/master/florida-blue-data.json',
                type = 'fill',
                color = 'rgba(40,0,113,0.8)'
            )
        ],
        accesstoken=mapbox_access_token,
        bearing=0,
        center=dict(
            lat=27.8,
            lon=-83
        ),
        pitch=0,
        zoom=5.2,
        style='light'
    ),
)

fig = dict(data=data, layout=layout)
py.iplot(fig, filename='county-level-choropleths-python')
Out[6]:

Reference

See https://plot.ly/python/reference/#scattermapbox for more information about mapbox and their attribute options.

Still need help?
Contact Us

For guaranteed 24 hour response turnarounds, upgrade to a Developer Support Plan.