Skip to content

Commit 6f1273d

Browse files
authored
Merge pull request #15 from PolicyEngine/paper
congressional district tesselation
2 parents 3463f4b + 03e1602 commit 6f1273d

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

reweighting/cd-plotting-tiles.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import geopandas as gpd
2+
from shapely import affinity
3+
import pandas as pd
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
7+
8+
# https://docs.google.com/spreadsheets/d/13XkF59JKzvw4SeSq5mbgIFrJfYjK4amg9JoQE5e9grQ/edit?gid=0#gid=0
9+
# https://www.dailykos.com/stories/2019/7/23/1873464/-We-took-the-best-map-ever-of-US-congressional-districts-and-made-it-even-better
10+
# https://www.primarycast.us/house-races/KY_2
11+
12+
# ----------------------------------------------------
13+
# read the hex-cartogram shapefile you downloaded
14+
# ----------------------------------------------------
15+
shp_path = r"/mnt/c/devl/data/pe/HexCDv31/HexCDv31.shp"
16+
17+
gdf = gpd.read_file(shp_path)
18+
19+
# QUICK sanity-check: take a look at the attribute names
20+
print(gdf.columns.tolist())
21+
print(gdf.head(3))
22+
23+
# ----------------------------------------------------
24+
nc = gdf[gdf["STATEAB"] == "NC"]
25+
26+
# ----------------------------------------------------
27+
# add your 14 numbers
28+
# ----------------------------------------------------
29+
my_numbers = np.random.rand(14)
30+
31+
vals = pd.DataFrame({
32+
"CDLABEL": range(1, 15),
33+
"metric": my_numbers
34+
})
35+
36+
nc["CDLABEL"] = nc["CDLABEL"].astype(int)
37+
38+
# ------------------------------------------------------------------
39+
# merge and plot
40+
# ------------------------------------------------------------------
41+
nc_plot = nc.merge(vals, on="CDLABEL", how="left")
42+
43+
fig, ax = plt.subplots(figsize=(6, 7))
44+
45+
# draw boundaries so the hexes have borders
46+
nc_plot.boundary.plot(ax=ax, edgecolor="black", linewidth=0.4)
47+
48+
# fill by your metric
49+
nc_plot.plot(column="metric",
50+
cmap="viridis", # pick any Matplotlib colormap
51+
linewidth=0,
52+
legend=True,
53+
ax=ax)
54+
55+
ax.set_title("North Carolina congressional districts", fontsize=13)
56+
ax.set_axis_off()
57+
plt.tight_layout()
58+
plt.show()
59+
60+
# Now rotate to make the state flat
61+
# pick a single pivot
62+
pivot = nc_plot.unary_union.centroid # nc_plot is your merged GeoDataFrame
63+
64+
# rotate every geometry around *that* pivot
65+
angle = -12
66+
nc_rot = nc_plot.copy()
67+
nc_rot["geometry"] = nc_rot.geometry.apply(
68+
lambda g: affinity.rotate(g, angle, origin=pivot)
69+
)
70+
71+
# 3) plot
72+
fig, ax = plt.subplots(figsize=(6, 7))
73+
nc_rot.boundary.plot(ax=ax, edgecolor="black", linewidth=0.4)
74+
nc_rot.plot(column="metric", cmap="viridis", linewidth=0, legend=True, ax=ax)
75+
76+
ax.set_title("One Household's Weight Values Across NC's 14 Districts", fontsize=13)
77+
ax.set_axis_off()
78+
plt.tight_layout()
79+
plt.show()
80+
81+

0 commit comments

Comments
 (0)