
6.2 Data¶
Part: 6 — Geographically Weighted Models (Chapter 6.2 of 14)
Dataset: diabetes_atlantic.shp (666 counties); data_1998_2010_long_lbc.csv (space-time panel); bundled simulation datasets
Focus: Every dataset used across Part 6, and a clear boundary between real data and API-demonstration data
Library: spatialstats.gwmodel (PySpatialStats)
1. Overview¶
Part 6 uses three distinct kinds of data, and it matters which is which: a real health dataset whose results
are genuine findings, a real space-time panel for the spatiotemporal chapters, and four small simulated
datasets bundled with the library purely to demonstrate API syntax quickly. Mixing these up — reporting a
load_georgia() coefficient as if it were a real Georgia finding — would misrepresent synthetic data as
evidence. This chapter draws the line explicitly before any modelling begins.
| Step | What we do |
|---|---|
| Real data | diabetes_atlantic.shp — the primary dataset for every substantive GWR result in this Part |
| Panel | data_1998_2010_long_lbc.csv — the space-time data GTWR (Chapter 6.10) needs |
| Simulated | The four bundled loaders, explicitly labelled as syntax demonstrations, never as findings |
2. Python Setup¶
import sys, warnings
from pathlib import Path
import numpy as np
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore", category=FutureWarning)
warnings.filterwarnings("ignore", category=DeprecationWarning)
def find_repo_root(start: Path = Path.cwd()) -> Path:
for p in [start, *start.parents]:
if (p / "pyproject.toml").exists() and (p / "data").is_dir():
return p
raise FileNotFoundError("Run this notebook from inside the PySpatialStats repository.")
ROOT = find_repo_root()
DATA = ROOT / "data"
try:
import spatialstats
except ImportError:
sys.path.insert(0, str(ROOT))
import spatialstats
from spatialstats.gwmodel.datasets import load_georgia, load_londonhouse, load_beijing_pm25, load_ncovid
plt.rcParams.update({
"figure.dpi": 100, "savefig.dpi": 100, "font.size": 10, "axes.titlesize": 11,
"axes.titleweight": "bold", "axes.spines.top": False, "axes.spines.right": False,
"axes.grid": True, "grid.alpha": 0.25, "legend.frameon": False,
})
C = {"blue": "#2b6cb0", "red": "#c0392b", "green": "#2f855a", "orange": "#dd6b20",
"grey": "#718096", "purple": "#6b46c1", "teal": "#2c7a7b"}
print(f"spatialstats : version {spatialstats.__version__}")
spatialstats : version 0.2.0
3. The Real Dataset: diabetes_atlantic¶
The same dataset used throughout Part 3: 666 Atlantic-seaboard counties, Dia_pct explained by six health and
access covariates, with centroids x, y already in EPSG:5070 (metres) — the projected CRS every GW model in
this library requires, since bandwidths are measured in coordinate units directly.
counties = gpd.read_file(DATA / "diabetes_atlantic.shp")
covariates = ["Obesity", "PhysInact", "Acc_Exer", "PCP_rate", "FoodEnvIdx", "SVI"]
print(f"counties: {counties.shape[0]}, CRS: {counties.crs.to_epsg()} (projected, metres)")
print(f"centroid x range: [{counties['x'].min():,.0f}, {counties['x'].max():,.0f}] m")
print(f"centroid y range: [{counties['y'].min():,.0f}, {counties['y'].max():,.0f}] m")
counties[["COUNTY", "STATE", "Dia_pct"] + covariates].describe().round(2)
counties: 666, CRS: 5070 (projected, metres) centroid x range: [949,877, 1,916,559] m centroid y range: [932,261, 2,623,675] m
| Dia_pct | Obesity | PhysInact | Acc_Exer | PCP_rate | FoodEnvIdx | SVI | |
|---|---|---|---|---|---|---|---|
| count | 666.00 | 666.00 | 666.00 | 666.00 | 666.00 | 666.00 | 666.00 |
| mean | 9.14 | 27.72 | 21.54 | 64.62 | 55.71 | 7.54 | 0.57 |
| std | 1.56 | 4.79 | 3.78 | 22.83 | 38.31 | 0.98 | 0.28 |
| min | 5.86 | 16.80 | 13.28 | 0.00 | 5.00 | 2.60 | 0.00 |
| 25% | 7.98 | 23.56 | 18.74 | 50.00 | 32.80 | 7.00 | 0.35 |
| 50% | 8.88 | 27.96 | 21.17 | 66.40 | 47.60 | 7.60 | 0.57 |
| 75% | 9.98 | 31.26 | 23.83 | 82.35 | 70.55 | 8.20 | 0.81 |
| max | 16.96 | 41.18 | 35.16 | 100.00 | 536.60 | 10.00 | 1.00 |
Every real GWR result in Chapters 6.4–6.9 and 6.12–6.14 is fit on this exact specification:
Dia_pct ~ Obesity + PhysInact + Acc_Exer + PCP_rate + FoodEnvIdx + SVI, the same one used in Part 3, so every
comparison against the global OLS/SLM/SEM models (Chapter 6.8) is apples to apples.
4. The Space-Time Panel¶
data_1998_2010_long_lbc.csv — already used in Part 3, Chapter 3.4 for the differential Moran's I example —
covers 3,107 US counties from 1998 to 2012 (its filename undersells its own date range) with five
environmental/health covariates and a mortality RATE. Chapter 6.10's GTWR needs both space and time
coordinates, so this is the only dataset in this Part with a genuine temporal dimension.
panel = pd.read_csv(DATA / "data_1998_2010_long_lbc.csv")
print(f"panel: {panel.shape[0]:,} rows, {panel['FIPS'].nunique():,} counties, "
f"years {panel['Year'].min()}-{panel['Year'].max()}")
panel.head(3)
panel: 46,605 rows, 3,107 counties, years 1998-2012
| FIPS | X | Y | Year | SMOKING | POVERTY | PM25 | NO2 | SO2 | RATE | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1001 | 872679.179 | 1094432.99 | 1998 | 27.0 | 11.3 | 17.08 | 1.38 | 0.057 | 90.63 |
| 1 | 1001 | 872679.179 | 1094432.99 | 1999 | 26.0 | 11.4 | 15.38 | 1.04 | 0.055 | 90.39 |
| 2 | 1001 | 872679.179 | 1094432.99 | 2000 | 26.0 | 10.5 | 14.04 | 1.47 | 0.054 | 89.47 |
For the space-time chapters, this Part uses the same 217 Northeast counties as Parts 2–5 (matched by FIPS), restricted to a handful of years — large enough to show genuine space-time structure, small enough to fit quickly (Chapter 6.12 times this precisely).
northeast = gpd.read_file(DATA / "diabetes_northeast.shp")
fips_ne = set(northeast["FIPS"].astype(int))
panel_ne = panel[panel["FIPS"].isin(fips_ne)]
print(f"Northeast subset: {panel_ne['FIPS'].nunique()} counties x "
f"{panel_ne['Year'].nunique()} years = {len(panel_ne)} rows")
Northeast subset: 217 counties x 15 years = 3255 rows
5. Bundled Simulation Datasets — API Demonstrations Only¶
spatialstats.gwmodel.datasets bundles four synthetic datasets, generated to exercise specific model
shapes (count outcomes, spatial PCA, etc.) quickly without downloading anything. Every result computed from
these four loaders in this Part is a syntax demonstration, not a finding — they are used exactly where the
outline calls for a quick API illustration (Chapter 6.6's GWGLM count-outcome demo, for instance) and nowhere
else.
demo_sets = {
"load_georgia": load_georgia, "load_londonhouse": load_londonhouse,
"load_beijing_pm25": load_beijing_pm25, "load_ncovid": load_ncovid,
}
rows = []
for name, loader in demo_sets.items():
gdf, features, target = loader()
rows.append({"loader": name, "n": len(gdf), "features": ", ".join(features), "target": target})
pd.DataFrame(rows)
| loader | n | features | target | |
|---|---|---|---|---|
| 0 | load_georgia | 159 | PctRural, PctBach, PctEld, PctFB, PctPov, PctB... | TotPop90 |
| 1 | load_londonhouse | 500 | FloorArea, Bathrooms, Bedrooms, DistCenter, Gr... | Price |
| 2 | load_beijing_pm25 | 300 | AOD, DEM, Wind, Humidity, Temperature | PM25 |
| 3 | load_ncovid | 400 | PopDensity, MedianAge, PctUninsured, HospBeds,... | MortalityRate |
None of these four represent real Georgia counties, real London house prices, real Beijing air quality, or real COVID mortality — they are synthetic data shaped like those domains, useful only for confirming a function call works as documented. Any chapter that uses one says so explicitly in its own text, exactly as this section does.
6. Summary and Conclusions¶
This chapter drew an explicit line between real and synthetic data before any modelling begins.
What we did¶
- Confirmed
diabetes_atlantic.shp's 666 counties, projected EPSG:5070 CRS, and the exact regression specification every later chapter's real GWR results use. - Confirmed the space-time panel's coverage (3,107 counties, 1998–2012) and built the 217-county Northeast subset Chapter 6.10 uses for GTWR.
- Loaded all four bundled simulation datasets and labelled them explicitly as API-demonstration-only data, never to be reported as real findings.
Practical takeaways¶
- Always check a bundled "example dataset"'s provenance before reporting a result from it — several libraries, this one included, ship synthetic data specifically for fast API demonstrations.
- Keeping the projected CRS in view (
x,yalready in metres here) matters immediately: every bandwidth in this Part is a distance or a neighbour count in these exact coordinate units.
Next steps¶
Chapter 6.3 (Kernels, Bandwidths and the Fitting Pattern) builds the full kernel and bandwidth-selection machinery on this chapter's real Atlantic-county data.
7. Resources¶
Textbooks¶
| Reference | Notes |
|---|---|
| Fotheringham, A. S., Brunsdon, C. & Charlton, M. (2002). Geographically Weighted Regression. Wiley. | Appendix data descriptions, the origin of the Georgia/London-style example datasets this library's bundled loaders are modelled on |
Key papers¶
| Paper | Contribution |
|---|---|
| — | This chapter is data preparation; see Chapter 6.1's resources for the foundational GWR literature |
In this library¶
| Object | Role |
|---|---|
spatialstats.gwmodel.datasets.load_georgia, load_londonhouse, load_beijing_pm25, load_ncovid |
Synthetic API-demonstration datasets |
| Chapter 6.3 | Where the real diabetes_atlantic data is first modelled |
| Chapter 6.10 | Where the space-time panel subset built here is used |