Project 5 — Migration & Housing Trends¶
Difficulty
🟡 Intermediate. ~12–16 hours.
Goal¶
"Where are people moving in and out of [your metro area], and how do those flows align with housing-price changes?"
Tell a temporal story by combining migration flows (origin → destination, by county) with housing-price trends (Zillow ZHVI or similar) at the tract or county level.
Data needed¶
| Layer | Source |
|---|---|
| US counties | TIGER/Line |
| County-to-county migration | Census ACS migration flows table |
| Median home value over time | Zillow ZHVI (county-level), https://www.zillow.com/research/data/ |
| (Optional) Tract-level home values | Census ACS B25077 |
| Metro area boundary | Census CBSA |
Tools used¶
- ArcGIS Pro: Add Join, Calculate Field, Spatial Join
- Time-aware layers, animations
- Layout multi-frame
- Charts (in pop-ups or dashboard)
Workflow¶
Step 1 — Set up¶
- Project:
migration_housing_<metro>. - Project to NAD83 / Conus Albers (EPSG:5070) for area-correct visuals.
- Filter counties to your metro CBSA.
Step 2 — Compute net migration¶
For each county:
def net_migration(in_flow, out_flow):
if in_flow is None: in_flow = 0
if out_flow is None: out_flow = 0
return in_flow - out_flow
Add field NET_MIG_2022. Repeat for several years.
Step 3 — Compute housing change¶
For each county:
def pct_change(now, then):
if now is None or then is None or then == 0: return None
return ((now - then) / then) * 100
Add field ZHVI_CHG_2018_2024 = pct_change(!ZHVI_2024!, !ZHVI_2018!).
Step 4 — Map both¶
Map A — Net migration (diverging)¶
- Symbology: Graduated Colors on
NET_MIG_2022. - Method: Manual (negative quantiles + 0 + positive quantiles).
- Color scheme: Diverging RdBu — losses red, gains blue.
Map B — Housing-price change¶
- Symbology: Graduated Colors on
ZHVI_CHG_2018_2024. - Sequential or diverging palette (depending on whether any counties saw declines).
- Match the 0% midpoint to neutral.
Step 5 — Detect patterns¶
Add a categorical field:
def category(net_mig, price_chg):
if net_mig is None or price_chg is None: return "Unknown"
if net_mig > 0 and price_chg > 0: return "Hot growth"
if net_mig > 0 and price_chg <= 0: return "Bargain growth"
if net_mig < 0 and price_chg > 0: return "Pricing out"
if net_mig < 0 and price_chg < 0: return "Decline"
return "Mixed"
Symbolize a third map by CATEGORY — this is the headline.
Step 6 — Time animation¶
If your data is a long table (year per row), create a time-aware feature class:
- Right-click layer → Properties → Time → Filter Layer Content based on attribute values.
- Set Time Field =
YEAR. - Open the Time ribbon → animate.
- Export as MP4 / GIF for your portfolio.
Step 7 — Layout / Story Map¶
A 4-section Story Map:
- Set the scene: "Where are Americans moving?"
- Net migration map (animated).
- Housing change map.
- Combined category map + 1-paragraph takeaway.
Skills learned¶
- Time-aware data
- Animation export
- Diverging vs sequential palettes
- Cross-source data joins (Zillow + Census)
- Categorical synthesis from multiple variables
Portfolio value¶
A real-estate / urban-planning power move. Combines analysis with storytelling and a topical question (post-COVID migration, remote work, housing affordability).
Stretch goals¶
- Add flow lines between origin and destination counties (use XY To Line + flow line styling).
- Use migration_flows OD table to map where people came from for any one county.
- Layer rent data alongside home values.
- Build a dashboard with toggle between metros for comparison.
→ Next: Site Suitability Analysis.