Choropleth with matplotlib and basemap

When I was using excel to make all of my graphs, the choropleth map was out of reach and particularly alluring. Later, using Stata, I figured out how to make choropleth maps, but the results were never quite right. Now, much later, excel has tools to make these maps easily, and so do you, even if you don’t have a modern copy of excel, by using python!

What follows is an example that maps 2017 GDP growth by Norwegian county.

First, GDP growth data is collected from the statistics office website. Next, shapefiles that match the regions in the data (NO_Fylker_pol_latlng) are downloaded and, using an online tool, simplified to 10% (because Norway has an extremely complex coastline). The simplified shapefiles are saved in a folder called shapefiles.

Python imports:

# Import packages 
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.colors import Normalize
from mpl_toolkits.basemap import Basemap as Basemap

Data from the Stats Office as dictionary d:

# data for choropleth
d = {'Østfold': 2.5,
 'Akershus': 2.5,
 'Oslo': 2.8,
 'Hedmark': 2.2,
 'Oppland': 2.3,
 'Buskerud': 2.0,
 'Vestfold': 2.1,
 'Telemark': 0.7,
 'Aust-Agder': 2.5,
 'Vest-Agder': 0.9,
 'Rogaland': -0.4,
 'Hordaland': 1.2,
 'Sogn og Fjordane': 1.6,
 'Møre og Romsdal': 0.7,
 'Sør-Trøndelag': 2.9,
 'Nord-Trøndelag': 2.9,
 'Nordland': 1.9,
 'Troms': 2.1,
 'Finnmark': 2.0}

Code creates the map:

# Create map with lcc projection and boundaries that tightly frame Norway
m = Basemap(llcrnrlon=5, llcrnrlat=57, urcrnrlon=33, urcrnrlat=71,
            projection='lcc', lat_1=57, lon_0=15)

fig = plt.figure(figsize=(8, 16))

m.drawmapboundary()   # Create space for drawing county shapes

# read shapefiles using latin-1 encoding and call shape data "no_co"
m.readshapefile('shapefiles/NO_Fylker_pol_latlng', 'no_co', 
                drawbounds=False,
                default_encoding='latin-1')

ax = plt.gca()   # Call the current plot area "ax"
ax.axis('off')   # Turn off border on outer edge of map

# Map values between -2 and 4 to colors in the rainbow_r colormap
cm = plt.cm.rainbow_r
norm = Normalize(-2, 4)

# For each county, select the face color and add shape to the map
for info, shape in zip(m.no_co_info, m.no_co):
    fc = cm(norm(d[info['NAVN']])) 
    ax.add_patch(Polygon(shape, fc=fc, ec='white', lw=0.5))
    
# Add title and colorbar legend
plt.title(f'Norway Real GDP Growth by County, 2017', fontsize=16)
cb = fig.colorbar(ax.imshow([np.array([-2, 4])], cm), shrink=0.25, pad=-0.3)
cb.outline.set_linewidth(0.1)

norway

Advertisements

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 )

Google photo

You are commenting using your Google 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