Map insets
files needed = ('cb_2021_us_state_5m.zip') [from here]
Our goal in this short notebook is to learn how to create insets.
Insets are maps within maps that are used when one part of the object being mapped is far from the rest of the object. The New York City subway map is a classic example. Showing the true postion of Staten Island relative to Manhattan would waste a lot of space, so it is inset into the map.
Showing Alaska and Hawaii some respect
If we try and plot all 50 states, Alaska and Hawaii mess things up. Often, people will just drop Alaska and Hawaii and only plot the contiguous U.S. states. I have a friend from Alaska who does not like this.
Let's add Alaska and Hawaii as insets to the contiguous U.S. states, or the 'lower 48' as my friend from Alaska calls it. Something like this, but without the random colors. Geez, Adobe.
The process here is similar to what we did with the legend in the choropleths notebook. We add a new axis to the existing axis and plot to it. The difference here is that our new axis will be inside the existing axis, rather than adjacent to it.
# The usual suspects
import geopandas
import matplotlib.pyplot as plt
# This is needed to create the inset in the figure
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
We have done this a few times now. Grab the state shape files (or find the ones you already have on your computer) and load them into a geodataframe.
states = geopandas.read_file('cb_2021_us_state_5m/cb_2021_us_state_5m.shp')
Plot the whole United States as it actually exists in space.
fig, gax = plt.subplots(figsize=(15,15))
states.plot(ax = gax, edgecolor='black',color='white')
gax.set_title('The United States', fontsize=20)
plt.show()
Oh boy. Alaska and Hawaii are drowning out the detail in the lower 48. We also have a problem with the some of the Aleutian Islands "wrapping around" and being plotted on the right side of the figure.
First, let's break out the lower 48, Alaska, and Hawaii in separate DataFrames.
codes = states.STUSPS.unique()
others = ['HI', 'VI', 'PR', 'AS', 'MP', 'GU', 'AK']
lower_48 = states[~states['STUSPS'].isin(others)]
ak = states[states['STUSPS']=='AK']
hi = states[states['STUSPS']=='HI']
What's wrong with Alaska?
Let's plot Alaska.
fig, ax = plt.subplots(figsize=(15,15))
ak.plot(edgecolor='black',color='white', ax=ax)
ax.set_title('Alaska', fontsize=20)
plt.show()
We still have this problem with the Aleutian Islands. We can fix this by switching to a coordinate reference system (CRS) that centers the map on Alaska. This CRS is EPSG 8806.
ak2 = ak.to_crs('EPSG:8806')
fig, ax = plt.subplots(figsize=(15,15))
ak2.plot(edgecolor='black',color='white', ax=ax)
ax.set_title('Alaska', fontsize=20)
plt.show()
Now we are in good shape.
Adding Alaska to the map
To create an inset, we create a new axis set into the original axis. We need the .inset_axes()
method
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
We imported inset_axis
in the first code cell above. To create the inset we use
axins = inset_axes(gax, width='100%', height='100%',
bbox_to_anchor=(-.05, 0, 0.3, 0.3),
bbox_transform=gax.transAxes )
The bbox_transform=gax.tranAxes
says that the units in the bbox_to_anchor
argument are the proportions of the original axes. For example, we put the left corner of the inset at (-0.5, 0) and the upper right corner at (0.3, 0.3).
fig, gax = plt.subplots(figsize=(15,15))
lower_48.plot(ax = gax, edgecolor='black',color='white')
gax.set_title('The lower 48 and Alaska', fontsize=20)
#plt.axis('off')
# Creat the inset.
axins = inset_axes(gax,width='100%', height='100%',
bbox_to_anchor=(-.05, 0, 0.3, 0.3),
bbox_transform=gax.transAxes )
# Plot Alaska on the inset axes.
ak2.plot(ax=axins, edgecolor='black', color='white')
#plt.axis('off')
plt.show()
Once we drop the axes, this looks good.
fig, gax = plt.subplots(figsize=(15,15))
lower_48.plot(ax = gax, edgecolor='black',color='white')
gax.set_title('The lower 48 and Alaska', fontsize=20)
plt.axis('off')
# Creat the inset.
axins = inset_axes(gax,width='100%', height='100%',
bbox_to_anchor=(-.05, 0, 0.3, 0.3),
bbox_transform=gax.transAxes )
# Plot Alaska on the inset axes.
ak2.plot(ax=axins, edgecolor='black', color='white')
plt.axis('off')
plt.show()
Practice: Squeezing in Hawaii
Add Hawaii to our map.
- Plot Hawaii by itself. Does it look okay?
# 1 Looks okay to me.
ax = hi.plot(facecolor='white', edgecolor='black')
ax.set_title('Hawaii', fontsize=20)
plt.show()
- Create another inset axis and add Hawaii to our plot from above. You will need to experiment with the size and location of the axis to make it look right. I find it helpful to leave the axis on while you do this and turn the axis off once you are happy.
Here are the details on inset_axis
if you are interested.
#2 Create a second inset axes. Plot Hawaii on it.
fig, gax = plt.subplots(figsize=(15,15))
lower_48.plot(ax = gax, edgecolor='black',color='white')
gax.set_title('The United States', fontsize=20)
# Plotting Alaska
plt.axis('off')
axins1 = inset_axes(gax, width='100%', height='100%', bbox_to_anchor=(-.05, 0, 0.3, 0.3),
bbox_transform=gax.transAxes )
ak2.plot(ax=axins1, edgecolor='black', color='white')
plt.axis('off')
# Plotting Hawaii
axins2 = inset_axes(gax,width='100%', height='100%',
bbox_to_anchor=(.25, .1, 0.1, 0.1),
bbox_transform=gax.transAxes )
hi.plot(ax=axins2, edgecolor='black', color='white')
plt.axis('off')
#plt.savefig('us.svg')
plt.show()