Map Demo

This demo is designed to show the difference in resolution and scope between the geometries returned by censusdis.maps.ShapeReader.read_shapefile and censusdis.maps.ShapeReader.read_cb_shapefile. The former returns high-resolution geometry focused on political boundaries that is useful for spatial joins. The latter returns lower resolution cartographic boundary geometries suitable for plotting maps.

Imports and configuration

[1]:
# So we can run from within the censusdis project and find the packages we need.
import os
import sys

sys.path.append(
    os.path.join(os.path.abspath(os.path.join(os.path.curdir, os.path.pardir)))
)
[2]:
from collections import OrderedDict

import matplotlib.pyplot as plt

from censusdis import states
from censusdis.maps import ShapeReader
[3]:
STATE = states.NJ
YEAR = 2010

Read the geometries

We will read both files for a variety of geoemetries. Note that blocks are quite small so there is no separate cartographic bounds version available.

[4]:
reader = ShapeReader(year=YEAR)
[5]:
shapefiles_by_geo = OrderedDict()
for geo in ["tabblock", "bg", "tract", "cousub"]:
    gdf = reader.read_shapefile(STATE, geo)
    shapefiles_by_geo[geo] = gdf
[6]:
cb_by_geo = {}
if YEAR >= 2010:
    for geo in ["bg", "tract", "cousub"]:
        gdf = reader.read_cb_shapefile(STATE, geo)
        cb_by_geo[geo] = gdf

Counties

County files are available on a nationwide basis, so we will load them that way and then filter down to just the state we want.

[7]:
gdf = reader.read_shapefile("us", "county")
shapefiles_by_geo["county"] = gdf[gdf["STATEFP"] == STATE]
[8]:
gdf_cb = reader.read_cb_shapefile("us", "county")
cb_by_geo["county"] = gdf_cb[gdf_cb["STATEFP"] == STATE]

Plot

Now let’s plot each geometrty side by side. You will see that the cartographic boundary versions still have plenty of detail to render nice maps, and that they also don’t extend out into bodies of water like the other versions do when, for example, a county, county subdivision, or census tract includes water.

[9]:
def plot(gdf, state, geo_name, ax):
    ax = gdf.boundary.plot(linewidth=1, ax=ax)

    state_name = states.NAMES_FROM_IDS[state]

    ax.set_title(f"{state_name}\n{YEAR} {geo_name}")

    ax.axis("off")
[10]:
for geo, gdf_shape in reversed(shapefiles_by_geo.items()):
    fig, axes = plt.subplots(1, 2, sharey=True, figsize=(8, 8))
    plot(gdf_shape, STATE, geo, axes[0])
    gdf_cb = cb_by_geo.get(geo, None)
    if gdf_cb is not None:
        plot(gdf_cb, STATE, f"{geo} Cartographic Boundaries", axes[1])
    else:
        axes[1].set_title("No Data")
        axes[1].axis("off")
../_images/nb_Map_Demo_14_0.png
../_images/nb_Map_Demo_14_1.png
../_images/nb_Map_Demo_14_2.png
../_images/nb_Map_Demo_14_3.png
../_images/nb_Map_Demo_14_4.png
[ ]: