Mapping US Census Data with Python
By: Jackson Gilkey
Tags: Maps, New York, Data Science, Census

Public Data

Mapping US Census Data with Python

If you’ve ever wanted to create quick geographic visualizations of your favorite Census statistics then you’ve come to the right place! First you’ll need to get your hands on the census data that you’re interested in. For this example, we’ll be using transportation data in New York state.

Data Download

Now you’ll want to import the required packages. If you are new to the censusdata package please take a moment to familiarize yourself using the excellent documentation or this introductory blog on the very subject

import pandas as pd

import censusdata

from tabulate import tabulate

Now we need to download the data we’re interested in.

df = censusdata.download('acs5',

2015,

censusdata.censusgeo([('state', '36'), ('county', '*')]),

['B08301_001E', 'B08301_010E'])

A quick breakdown on the parameters of this method:

‘acs5’ refers to the 5 Year American Community Survey and designates the database we are downloading from.

refers to the 5 Year American Community Survey and designates the database we are downloading from. 2015 is the year that we are getting data from

is the year that we are getting data from censusdata.censusgeo([(‘state’, ‘36’), (‘county’, ‘*’)]) defines the geography we are interested in. The ‘36’ value is the FIPS (Federal Information Processing Standards) code for New York state while the ‘*’ means we want every county. To look up your own state or county FIPS code refer to the Wikipedia page.

defines the geography we are interested in. The ‘36’ value is the FIPS (Federal Information Processing Standards) code for New York state while the ‘*’ means we want every county. To look up your own state or county FIPS code refer to the Wikipedia page. [‘B08301_001E’, ‘B08301_010E’] this is a list referring to the specific two tables that we are interested in. Note that these were located beforehand using the search function of censusdata.

Dataframe Prep

Now let’s take a look at what's in our dataframe.

print(tabulate(df, headers='keys', tablefmt='psql'))

Okay, we are definitely getting the raw information we want in this table but right now it’s a bit cumbersome to interpret. For instance, the Id values here are censusgeo objects. Yikes!

First, we’ll change the existing column names away from those table Ids to reflect their contents.

column_names = ['total_transpo', 'total_public_transpo']

df.columns = column_names

Next, we’ll engineer a new column that's just the ratio of public transit.

df['percent_public_transpo'] = df.apply(

lambda row: row['total_public_transpo']/row['total_transpo'],

axis = 1)

Now we’ll redefine the index while extracting the county name.

new_indices = []

county_names = [] for index in df.index.tolist():

new_index = index.geo[0][1] + index.geo[1][1]

new_indices.append(new_index)

county_name = index.name.split(',')[0]

county_names.append(county_name) df.index = new_indices

df['county_name'] = county_names

Okay, let’s take another look.

Much better! Now onto the mapping

Mapping

To do the mapping we’ll be using a plotly feature called figure_factory that's going to do a lot of the work for us. So the first thing is to import the package.

import plotly.figure_factory as ff

Now creating the map is just a few lines of code.

fig = ff.create_choropleth(fips=df.index,

scope=['New York'],

values=df.percent_public_transpo,

title='NY Public Transit Use by County',

legend_title='% Public Transit')

fig.layout.template = None

fig.show()

Looks pretty good for a few lines of code! But don’t be fooled, we worked to set ourselves up for success here by structuring our dataframe in a way that's compatible with figure_factory. For instance, it takes in FIPS data in the form of state_code + county_code. So by renaming our indices to follow that form, we can simply pass the direct index values into the method

Finally, the data in this map is distributed in a way that we would expect, with a huge hotspot centered around NYC that fades the further out you go.

That's all there is to it, now get mapping!