I have a shapefile of major roadways in New Hampshire (TIGER/Line) obtained from the U.S Census Bureau (file found here), and am attempting to plot them using the Cartopy/Matplotlib tandem.
The Shapefile's Attributes
The shapefile attribute is split into four classes: LINEARID
, FULLNAME
, RTTYP
, & MTFCC
First Approach | Plot All Lines
The first approach was to load the shapefile in using cartopy.feature and plot it, which can be seen in the following code snippet. This worked as expected, and plotted every road line contained within the shapefile:
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
roads = '/path/to/file/majorroads.shp'
roads_feature = ShapelyFeature(Reader(roads).geometries(), crs.LambertConformal(), facecolor='none', edgecolor='gray')
ax.add_feature(roads_feature, linewidth=0.75)
Second Approach | Plot Specific Attribute
The second approach was to use the Cartopy Reader to locate and only plot lines that met a specific attribute. After reading this article from NASA, I used examples to write the following code:
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
roads = '/path/to/file/majorroads.shp'
roads_feature = Reader(roads)
parts = roads_feature.records()
for part in parts:
if part.attributes['FULLNAME'] == 'US Hwy 202':
ax.add_geometries(part.attributes, linewidth=0.50, facecolor='none', edgecolor='gray')
This did not plot the desired lines in the shapefile. What corrections can be made to ensure this code works correctly?
The best solution to execute this task is to utilize the Geopandas library in Python. My code was inspired from this web article, however I've expanded on its use somewhat in the answer below.
Code Snippet
import geopandas as gpd
data = gpd.read_file('/path/to/file/majorroads.shp')
sorted = data[(data.RTTYP == 'I') | (data.RTTYP == 'U') | (data.FULLNAME == 'State Rte 101') | (data.FULLNAME == 'Rte 101')]
ax.add_geometries(sorted.geometry, crs=crs.LambertConformal(), linewidth=1.00, facecolor='none', edgecolor='gray')
Important Notes
The shapefile is read into a familiar dataframe structure as seen in Pandas use. You'll notice: data[(data.RTTYP == 'I') | (data.RTTYP == 'U') | (data.FULLNAME == 'State Rte 101') | (data.FULLNAME == 'Rte 101')]
This use of element-wise logic was derived from this example, which can be expanded to other larger, data-rich shapefiles