25  Spatial Dynamics in Math Achievement

Rather than looking at the pooled data, SEDA also provides a long-form of their grade-corhort-standardized data, which is recommended for public presentation. That dataset contains observations at the district level for each year between 2009 and 2018. Using geosnap we can also examine how educational achievement has evolved over time and space. Here, we focus on math scores.

Code
import contextily as ctx
import geopandas as gpd
import geosnap.analyze as gaz
import geosnap.io as gio
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from geosnap.analyze.dynamics import draw_sequence_from_gdf
from geosnap import DataStore
from geosnap import visualize as gvz
from libpysal.weights import Rook
from mapclassify.classifiers import Quantiles

datasets = DataStore()
Code
ca_dists = datasets.nces(dataset="school_districts")
ca_dists = ca_dists[ca_dists.STATEFP == '06']

seda_dists = datasets.seda(
    accept_eula=True, level="geodist", pooling="long", standardize="gcs"
)

math_dists = seda_dists[seda_dists["subject"] == "mth"]
math_dists = math_dists.groupby(["sedalea", "year"]).mean(numeric_only=True)  # average over all grades
math_dists = math_dists.dropna(subset=["gcs_mn_all"])
math_dists = math_dists.reset_index()
math_dists["gcs_mn_all"] = (
    math_dists["gcs_mn_all"] - math_dists["grade"]
)  # I think this is how you're supposed to handle averaging over grades
math_dists = gpd.GeoDataFrame(
    math_dists.merge(
        ca_dists.drop(columns=["year"]), right_on="GEOID", left_on="sedalea"
    )
)
/Users/knaaptime/miniforge3/envs/urban_analysis/lib/python3.12/site-packages/geosnap/_data.py:255: UserWarning: Streaming data from SEDA archive at <https://exhibits.stanford.edu/data/catalog/db586ns4974>.
Use `geosnap.io.store_seda()` to store the data locally for better performance
  warn(msg)

Plotting the average math achievement over time shows a relatively steady increase, though still more than half a grade below the national average (as the line never raises above -0.5 on the Y-axis)

Code
math_dists.groupby('year').mean(numeric_only=True)['gcs_mn_all'].plot()

For a reminder of the general geography of math achievement, we can plot the data from 2018

Code
math_dists[math_dists.year == 2018][["gcs_mn_all", "geometry"]].dropna().explore(
    "gcs_mn_all",
    scheme="quantiles",
    k=8,
    cmap="PRGn",
    tiles="CartoDB Positron",
    style_kwds={"weight": 0.5},
)
Make this Notebook Trusted to load map: File -> Trust Notebook