Explore regional data

Try this page interactively — no install needed.

The Explore module is your first look at a regional dataset — before you estimate a single model. This page is a case study: you have just been handed 520 Indian districts observed by DMSP-OLS satellite nighttime lights between 1996 and 2010 (from Mendez, Kabiraj & Li) and asked three questions an analyst always starts with: is development spatially clustered, where exactly, and how did the whole regional distribution move over time?

Every Explore function takes the panel and returns a small result object carrying a tidy .df plus an interactive Plotly figure (.fig), and most offer a plain-language .interpret(). Read this page top to bottom: the functions are ordered as a workflowload the three inputs → map the level → encode the neighborhood → test and localize clustering → watch the distribution move in time and space.

Note

This is exploratory analysis: every reading below describes an association, never a cause. The Analyze module turns these patterns into estimates, and Learn explains the ideas behind them with simulations you control.

Stage 0 — Load the three inputs

geometrics separates geometry, data, and metadata: a geometry with only the entity ID (gdf), a long-form panel (df), and a data dictionary (df_dict). The bundled India case study ships all three; set_labels attaches the dictionary’s labels to every future figure and declares the (entity, time) coordinates once.

import warnings

warnings.filterwarnings("ignore")

import geometrics as gm

gdf, df, df_dict = gm.data.load_india()
df = gm.set_labels(df, df_dict, set_panel=True)  # labels + entity/time + roles, once
df.head(3)
statedist state district year ntl_rural ntl_urban ntl_total ntl_pc_1996 log_ntl_pc_1996 growth_ntl_pc_9610 ... latitude rural_share log_pop_density sc_share st_share work_share literacy_share higher_edu_share electricity_share log_paved_roads
0 Andhra PradeshAdilabad Andhra Pradesh Adilabad 1996 35532.074 8465.7354 43997.809 0.019194 -3.953148 0.039751 ... 19.25 0.948856 5.205684 0.188309 0.16231 0.439483 0.414134 0.043333 0.454379 4.301359
1 Andhra PradeshAdilabad Andhra Pradesh Adilabad 1999 51730.660 9121.8799 60852.539 0.019194 -3.953148 0.039751 ... 19.25 0.948856 5.205684 0.188309 0.16231 0.439483 0.414134 0.043333 0.454379 4.301359
2 Andhra PradeshAdilabad Andhra Pradesh Adilabad 2000 63759.672 10821.1310 74580.805 0.019194 -3.953148 0.039751 ... 19.25 0.948856 5.205684 0.188309 0.16231 0.439483 0.414134 0.043333 0.454379 4.301359

3 rows × 28 columns

The dictionary is data too — it documents every column and drives the labels on every figure:

df_dict.head(8)
var_name var_def label type role can_be_na
0 statedist Unique district identifier formed by concatena... State-district ID entity NaN False
1 state Name of the Indian state or union territory th... State factor NaN False
2 district Name of the district under 1991-census boundar... District factor entity_name False
3 year Observation year of the radiance-calibrated DM... Year time NaN False
4 ntl_rural Radiance-calibrated DMSP-OLS total nighttime l... Rural NTL numeric NaN False
5 ntl_urban Radiance-calibrated DMSP-OLS total nighttime l... Urban NTL numeric NaN False
6 ntl_total Radiance-calibrated DMSP-OLS total nighttime l... Total NTL numeric NaN False
7 ntl_pc_1996 Radiance-calibrated nighttime luminosity per c... NTL per capita (1996) numeric NaN False

Stage 1 — See the map

explore_choropleth_map classifies with mapclassify (Fisher-Jenks by default, k classes) and draws one legend entry per class, so the legend is the classification:

gm.explore_choropleth_map(df, "ntl_total", gdf=gdf, period=2010).fig

Pass animate=True instead of a single period to play the whole 1996–2010 film, or switch scheme ("quantiles", "equalinterval", …) to see how much the story depends on the classification — gm.explain("choropleth_classification") explains why.

Stage 2 — Encode the neighborhood

Everything spatial starts with a weights matrix W — the formal answer to “who is whose neighbor?”. The paper uses 6 nearest neighbors; explore_connectivity_map draws the graph so you can inspect it before trusting it:

w = gm.make_weights(gdf, method="knn", k=6)
gm.explore_connectivity_map(gdf, w=w).fig