analyze_gwr

analyze_gwr(
    df,
    outcome=None,
    covariates=None,
    *,
    gdf,
    period=None,
    entity=None,
    time=None,
    bw=None,
    fixed=False,
    kernel='bisquare',
    criterion='AICc',
    standardize=False,
    alpha=0.05,
    tiles=None,
    title=None,
)

Fit a geographically weighted regression and map each local surface.

A separate distance-weighted regression of outcome on covariates is calibrated at every entity (mgwr’s GWR), so each term’s coefficient becomes a local surface. The bandwidth is selected by golden-section search on criterion when bw is None; local significance applies the da Silva & Fotheringham multiple-testing correction (corrected alpha → critical t) at the nominal alpha level, and non-significant units are greyed on the coefficient maps.

Parameters

Name Type Description Default
df pd.DataFrame Long panel (or cross section) holding the outcome and covariates per entity. required
outcome str | None Numeric outcome column. Defaults to the outcome declared via :func:geometrics.set_roles. None
covariates str | Sequence[str] | None Numeric covariate column(s). Default to the covariates declared via :func:geometrics.set_roles. None
gdf gpd.GeoDataFrame Entity geometry; must carry the same entity-id column as df. Calibration coordinates are the polygon centroids in a metric CRS. required
period Any Period to analyze. Defaults to the latest period when df has a time dimension (a note records this). None
entity str | None Panel identifiers; default to the ids declared via :func:geometrics.set_panel. None
time str | None Panel identifiers; default to the ids declared via :func:geometrics.set_panel. None
bw float | None Bandwidth: number of nearest neighbors when fixed=False (adaptive), a distance in metric-CRS units when fixed=True. None (default) selects it by golden-section search on criterion. None
fixed bool Use a fixed-distance kernel instead of an adaptive nearest-neighbor one. False
kernel str Kernel weighting function: "bisquare" (default), "gaussian" or "exponential". 'bisquare'
criterion str Bandwidth-selection criterion: "AICc" (default), "AIC", "BIC" or "CV". 'AICc'
standardize bool Z-standardize the outcome and covariates before fitting, so local coefficients are comparable across terms (a note records this). False
alpha float Nominal significance level for the corrected local t-tests. 0.05
tiles str | None MapLibre base-map style for the coefficient maps, or None (default) for the vector backend (deterministic PNG export). None
title str | None Title for the local-R² map; per-term maps append the term label. None

Returns

Name Type Description
GWRResult Frozen result with the per-entity local frame (df), one diverging coefficient map per term (figs), the local-R² map (fig), the global summary table (gt) and the fitted mgwr results (model_obj).

Raises

Name Type Description
KeyError If the outcome or a covariate is not a column of df.
TypeError If a focal variable is not numeric, or df/gdf have the wrong type.
ValueError If roles cannot be resolved, arguments are invalid, or too few complete observations remain after alignment.

Examples

A 3x3 lattice with an explicit bandwidth (skipping the search):

import geopandas as gpd
import pandas as pd
from shapely.geometry import box

from geometrics.gwr import analyze_gwr

gdf = gpd.GeoDataFrame(
    {"cell": [f"c{i}" for i in range(9)]},
    geometry=[box(78 + i % 3, 20 + i // 3, 79 + i % 3, 21 + i // 3) for i in range(9)],
    crs="EPSG:4326",
)
df = pd.DataFrame(
    {
        "cell": [f"c{i}" for i in range(9)],
        "x1": [0.1, 0.9, 0.4, 0.7, 0.2, 0.8, 0.5, 0.3, 0.6],
        "y": [0.2, 1.4, 0.8, 1.5, 0.6, 2.0, 1.4, 1.0, 1.9],
    }
)
res = analyze_gwr(df, "y", ["x1"], gdf=gdf, entity="cell", bw=8, tiles=None)
print(res.bw, sorted(res.figs))