#+TITLE: Virginia 2026 amendment results: who crossed party lines #+CREATED: 2026-11-04 * What this is Scripts that pull Virginia's November 2026 general election results and estimate how Democratic (Warner) and Republican (Mizusawa) voters split on the three constitutional amendments: abortion, same-sex marriage and restoring voting rights to people with felony convictions. Backs the post in [[file:posts/spot-on-backwards/outline.org][posts/spot-on-backwards]]. * Running it #+begin_src sh bin/fetch # results, turnout, absentee counts; Census race + income (-E / -C for one half) bin/analyze # writes out/analysis.json and prints the summary bin/mkchart # out/crossovers.png, the dot-grid chart used in the post #+end_src =data/= and =out/= are regenerated and not committed. =bin/fetch= needs =jq=, =opassist= (Census key in 1Password: "api.census.gov API key") and Chrome for the chart. Everything else is Python's standard library. * Sources - Virginia Department of Elections, Election Night Reporting, 2026 November General: [[https://enr.elections.virginia.gov/results/public/virginia/elections/2026-November-General/reports][reports page]]. Three downloads: "Election Results" (one row per candidate or Yes/No per precinct), "Election Turnout" (registered voters per precinct) and "EnrAbsenteeRawCSV" (early and mail ballots returned, by locality, age and gender; no votes). - US Census Bureau, 2020 Census Redistricting Data (PL 94-171), table P4, adults by race, by voting district, via api.census.gov. - US Census Bureau, American Community Survey 2019-2023 5-year, table B19013, median household income by county or city. * Data notes - The site's page is a JavaScript app. Its JSON record is at =/results/public/api/elections/virginia/2026-November-General=, and downloads live at =/cdn/results//=. Blob names change on every publish, and a report sometimes drops out of a publish for a few minutes; =bin/fetch= keeps the previous copy when that happens. - The results CSV is Latin-1, not UTF-8. - *Early votes are missing for many localities.* As of the Nov 4 morning publishes, about 48 localities' totals look complete (half or more of registered voters), while about 72 look Election-Day-only (Arlington, Alexandria, Loudoun, Prince William, Chesterfield, Virginia Beach and others), with returned absentee ballots roughly equal to everything reported. =bin/analyze= reports both the all-precinct and the complete-localities-only numbers. The crossover rates barely differ; the statewide percentages do. - Precincts are matched to 2020 Census voting districts by locality and simplified name, not by number: numbers shifted in several counties (all of Henrico is off by one). About 75% of precincts match. * Method Two-group (Goodman) ecological regression across precincts with at least 100 Senate votes, weighted by Senate votes: a precinct's yes share is modeled as Republican-yes-rate x (1 - Warner share) + Democratic-yes-rate x Warner share. The 95% ranges come from resampling whole localities. These are estimates from precinct totals, not individual ballots, and assume each party's voters behave about the same everywhere. That assumption holds reasonably for abortion and voting rights and breaks for marriage, which varies sharply with a precinct's Black share. The analysis was built with Claude (Claude Code) and checked by an independent Claude agent, ChatGPT (gpt-5.5) and Gemini; see the Nov 4 session.