"From manufacturing belt, to rust belt, to college country"

A Visual Narrative of the US Urban Growth

[Dani Arribas-Bel & Michiel Gerritse]

Results and code


In the paper, we interpret the model output by visualizing the regression results of the "data preparation" page. Our goal was to make insightful how a phenomon like manufacturing or service sector specialiization affects cities, split out by city and conveying what type of effect it was (e.g. did it mostly affect firms, or people). Moreover, we organize these maps and figures to get an idea of how these effects change over time.

This page presents the code required to recreate the visualizations presented in the paper. All the code for this section was written in the Python language and executed from the IPython notebook. If you want to run it on your own machine, you can access this page as a notebook in the code repository.

Dependencies and requirements

Besides the standard libraries listed in cell [2] (pandas, matplotlib and numpy), you will need to have the file tools.py in the same folder as the notebook (it is by default in the repository). This module contains all the specific code we wrote to create the visualizations in the paper.

In [1]:
%matplotlib inline
In [2]:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import tools
from matplotlib.collections import LineCollection
In [3]:
f_link = 'data/robackeffects.csv'
db = tools.load_coefs(f_link)
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1419 entries, 0 to 1464
Data columns (total 23 columns):
year               1419 non-null int64
metarea            1419 non-null float64
wevalmeantemp      1268 non-null float64
revalmeantemp      1268 non-null float64
wevalmaxtemp       1268 non-null float64
revalmaxtemp       1268 non-null float64
wevalheating       1268 non-null float64
revalheating       1268 non-null float64
wemanufacturing    1110 non-null float64
remanufacturing    1110 non-null float64
weservice          1151 non-null float64
reservice          1151 non-null float64
wecollege          1280 non-null float64
recollege          1280 non-null float64
wek                1280 non-null float64
rek                1280 non-null float64
cat                1268 non-null object
color              1268 non-null object
lat                1419 non-null float64
lon                1419 non-null float64
x                  1419 non-null float64
y                  1419 non-null float64
pid                1419 non-null object
dtypes: float64(19), int64(1), object(3)

Single figures


The snapshots are essentially geographical maps that show the model’s results in a single year. Here we reproduce Figure 1(a) in the paper, which represents the snapshot of manufacturing in 1970. We use the following color coding:

  • green denotes a role as consumption amenities (rising rents, falling wages);
  • blue represents production amenities (rising rents, rising wages);
  • purpe for consumption disamenities (falling rents, rising wages);
  • and brown for production disamenities (falling rents, falling wages).

NOTE: The code below renders an image within the notebook. If you want to generate a png file, append the argument saveto=[PATH] to the function, replacing [PATH] by the preferred location for the figure (path should be to a file to be created).

In [4]:
_ = tools.level_map(db, year=1970, var='manufacturing', duct=['size', 'int'])

As explained in the paper, the brown color of the dots indicates a production disamenity: in this case, the concentration of manufacturing sectors drive away firms from cities. We conclude this based on the fact that manufacturing intensity decreases (in percentages) wages and rents. For many cities, the effects are not very strong; most effects concentrate in the North East. To summarize the strength of an effect, we consider the log-change in rents and wages. This implies we are looking at percentage changes in the variables (a 10% rent increase in San Francisco and Jacksonville are arguably more comparable than a 100$ rent increase). The intensity of the effect is determined by the hypotenuse of both effects – as explained in the paper.


Snapshots are connected by a transition plot that makes explicit the direction cities took from one period to the next. The following reproduces Figure 1(b) in the paper, which represents the transition of manufacturing from 1970 to 1980.

NOTE: The code below renders an image within the notebook. If you want to generate a png file, append the argument folder_out=[PATH] to the function, replacing [PATH] by the preferred location for the figures to be created (path should be to a folder, NOT to a file to be created).

In [5]:
tr_db = pd.concat([db[db['year']==1970], db[db['year']==1980]])
_ = tools.auto_fig(tr_db, tools.var_transition_sf, 'manufacturing')

In the directional plot, we try to convey the changes in the nature of a (dis-)amenity. As discussed in the paper, the effect of a variable on land prices and wages reflects how it changed the city: a variable that increases rents and wages acts as a production amenity; a variable that increases rents but decreases wages acts as a consumption amenity. Vice versa, if a variable decreases rents and wages, it apparently drives away firms – it is a production disamenity – and if the variable decreases rents but increases wages, it drives away people: it is a consumption disamenity.

To capture how the effects of, say, manufacturing sectors or college graduates change over time, we look at the change in their effect on the land price and wages. The argument here is that if the cities’ percentage wage and rent increases due to college graduates increase over time, college graduates have further turned into a production amenity. We calculate this change over the original effect for every city. By rescaling the initial effect to [0,0] the change in effect is summarized in a vector, whose direction suggest a change in the nature of the amenity (the quadrants indicate the type). Each line corresponds to one city on the map.


By alternating maps with the directional plots that occurred in between them, we hope to convey a sense of change what drove city growth and decline. We dubbed the chronological ordering op maps and directional plots a “storyboard”.

NOTE: the following code assumes the individual images have already been created previously using the methods above, and it displays them in the correct order.


In [6]:
_ = tools.build_storyboard('manufacturing', 'figs_sizeInt/')

Industrial specialization

In [7]:
_ = tools.build_storyboard('k', 'figs_sizeInt/')


In [8]:
_ = tools.build_storyboard('college', 'figs_sizeInt/')


In [9]:
_ = tools.build_storyboard('service', 'figs_sizeInt/')