← Election MapsElection Maps methodology
Version 1.1.1 · documented November 2, 2026 · Together Louisiana
This document describes the calculations implemented by the map. It is maintained with the working application and its tests. It does not adopt a new polling model or revise historical source data. The published methodology page is built from this exact document.
What is compared
Two independently selected elections, A and B, use the same map mode, voting method, geography, turnout measure and population group. The comparison is always B minus A, calculated before display rounding. Changing controls does not silently replace either election.
Turnout uses official observed participation for the selected election date. A 2026 survey selection resolves to the actual dated official early-turnout source in Turnout mode; respondents are never counted as turnout. In Results mode, the survey selection uses its frozen weighted candidate-support estimates and is labeled as a poll.
Measures and denominators
Candidate or party vote share
Candidate share = 100 × selected candidate votes ÷ all valid votes in the selected contest and method.
For contests with multiple Democratic or Republican candidates, the candidate selector also offers All Democrats (combined) and All Republicans (combined). These use the same summed party counts as the party-share measures. For the 2022 Senate election, the Democratic total combines Mixon, Chambers, Mendoza, Rodriguez and Steib; the Republican total combines Graham and Kennedy. Other parties remain in the all-valid-votes denominator. These are separate party totals, not a two-party-only renormalization. Individual candidate choices remain available. Combined selections persist in shared URLs and are identified in CSV exports.
Democratic or Republican share combines every candidate assigned to that party. Votes for other candidates stay in the denominator. Registration party is not substituted for candidate support. A zero or absent contest total has no defined share.
Vote-share change = B vote share − A vote share, in percentage points. The optional party-lead measure uses 100 × (Republican votes − Democratic votes) ÷ all valid votes; it is a different measure and can change by more than 100 points when a large lead reverses.
Implementation: atlas/dist/comparison-data.mjs, function resultMeasure; selected comparisons and rounding are applied in atlas/dist/app.js.
Turnout rate
Turnout rate = 100 × participants in the selected group and voting method ÷ registered voters in that group.
Each election uses the latest available registration snapshot in its own calendar year, dated on or before the election, matched to the same state, parish or exact normalized reported precinct code. Snapshots include active and inactive registrations. No future year, neighboring area, older-area fallback or guessed precinct allocation supplies a missing denominator. Missing or zero denominators and participation exceeding registration have no displayed turnout rate.
Rate change = B rate − A rate, in percentage points.
Implementation: atlas/dist/registration-data.mjs, functions selectRegistrationSnapshot, registrationAt and registrationMetrics; tests in atlas/tests/registration.mjs.
Vote share of the electorate
Group vote share = 100 × group participants ÷ all participants in that same election, method and geography.
This is the racial or registered-party composition of participants, not a candidate's support. Share change is B share − A share, in percentage points. State and parish summaries divide summed group counts by summed total counts; they do not average precinct percentages.
Registered share = 100 × registered group ÷ all registered voters in the matching dated snapshot.
Representation gap = participant share − registered share. A positive gap is above the group's registered-voter share; a negative gap is below. It is not a claim about eligible population representation or candidate choice.
Implementation: atlas/dist/comparison-data.mjs, functions electorateShare and turnoutTotals; atlas/dist/registration-data.mjs, functions registrationMetrics and representationLabel.
Voter count
Count change = B group participants − A group participants.
Relative count change = 100 × (B count − A count) ÷ A count. It is undefined when A is zero. A reported zero is retained as a zero; a missing value remains unavailable.
Implementation: atlas/dist/comparison-data.mjs, function percentCountChange.
Population groups
Race and registered-party choices are alternative marginal groupings. Selecting a race resets party to All, and selecting a party resets race to All. The underlying historical reports do not support invented joint groups such as Black Democrats.
Race uses All, Black, White and the source's combined Other category. Party uses All, Democrat, Republican and Other/no party. These are registrations at the election source date, not inferred candidate preferences.
Implementation: atlas/dist/comparison-data.mjs, function turnoutGroupRows; source group columns remain in the public snapshot.
Whole election, early vote and Election Day
Whole-election turnout comes from official post-election participation reports. Early Vote comes from dated early/absentee participation reports. The map does not manufacture Election Day turnout by subtracting incompatible early reports from final reports. Separate compatible Election Day participant totals remain unavailable where the source catalog says so.
Parish candidate results have whole-election, early/absentee and Election Day components. Whole-election returns can also include provisional votes. Existing validation retains the identity whole = early + Election Day + provisional for compatible records.
The supplied precinct candidate returns are Election Day returns. Parish early/absentee votes are not allocated to precincts. The poll supports Early Vote only. Unsupported combinations show unavailable data rather than substituting a different election or method.
Implementation: atlas/dist/voting-method.mjs; tests in atlas/tests/voting-method.mjs. Historical reconciliation receipts are preserved under atlas/validation/ and describe their specific snapshot, not every future source.
Poll estimates and small samples
The map displays the adopted aggregate survey model preserved in atlas/dist/data/poll.json and poll-precinct.json. Its source dataset, weighting run, raw and effective sample counts, response cutoff, electorate target cutoff, exclusions and proxy-profile notes belong to that frozen source. The map does not refit or silently refresh those weights.
The imported Site version 42 snapshot contains the October 30 survey model with 2,301 complete-profile candidate answers. This is a dated map snapshot, not a claim that the separate private analysis warehouse has no newer survey. Every data update must revise the source metadata and checksum manifest together.
• Five or more raw candidate answers: solid arrow.
• Two to four raw candidate answers: dotted arrow and a small-sample label.
• Zero or one raw candidate answer: no displayed local support estimate.
Eligibility uses raw candidate answers, not weighted counts or effective sample size. Dotted arrows and ranked poll outliers are descriptive; they are not significance tests. Coverage and nonresponse errors are not removed by weighting. No unsampled precinct estimate is fabricated.
Implementation: atlas/dist/comparison-data.mjs, function eligibleResult; atlas/dist/app.js; atlas/tests/poll-samples.mjs.
Arrows, color and numeric labels
Results arrows point 45 degrees upward left or right according to the selected comparison. Turnout arrows use the same tapered silhouette and point upward for an increase and downward for a decrease. Each stem begins at a narrow tail and widens into a normally proportioned arrowhead. The short connector between the arrow tail and numeric label has been removed.
Stem length represents the magnitude of the selected percentage or percentage-point change. Results width represents the absolute selected vote-share change expressed as a vote equivalent at a fixed historical valid-vote total. Turnout width represents the absolute actual group-participant count change.
Results vote equivalent = absolute share difference ÷ 100 × reference historical valid votes.
When both sources are historical elections, the later election supplies that reference total; ties use stable contest/total ordering. For a poll comparison, the historical election supplies it. Swapping A and B retains the same reference. Poll sample size is never used as election turnout. This standardized quantity is not an observed count of people switching candidates and is not a forecast of 2026 vote totals.
Turnout color runs from red for decreases through ochre/yellow at zero to dark green for increases. Rate and electorate-share color reaches its endpoints at ±10 percentage points; count color uses ±50 percent relative change. Undefined percentage changes use gray. Color saturation can reach an endpoint while the underlying numeric change continues beyond it.
Numeric labels show one decimal and stay associated with their own arrow inside their geography when space allows. Additional labels appear as zoom creates room. Counts and percentages are computed from unrounded data. Tail connectors are not drawn.
Implementation: atlas/dist/vote-impact.mjs, turnout-arrow.mjs, atlas-analysis.mjs, value-labels.mjs and app.js; corresponding tests are in atlas/tests/.
Outliers
At parish level, highlight the five highest and five lowest comparable changes in the current comparison area. At precinct level, use fifty of each. Ties have stable geographic ordering; small sets shrink into disjoint high and low sets. Missing changes are excluded.
Rankings do not add boundary outlines, shading or dimming. Hover and selected-area borders remain available for navigation. Outlier means highest/lowest observed change in this selection, not statistically unusual, reliable, or causally explained. Sparse local poll cells can rank as outliers and retain their sample warnings.
Implementation: atlas/dist/atlas-analysis.mjs, function rankOutliers.
Elections, geography and coverage
Minor elections start off. The major list contains presidential, U.S. Senate general/runoff and governor contests, including Louisiana all-candidate governor elections, plus the current map survey. Full catalogs remain available with Include minor elections. Election choices are stable when controls change.
Parish aliases are canonicalized explicitly. Ward/precinct codes are normalized by the strict parser. Current Louisiana precinct polygons and supplementary aggregate centroid anchors locate reported source codes. Historical boundary equivalence has not been established; the map does not pretend to reallocate results onto identical historical boundaries. Unlocated records remain in tables and downloads.
Source coverage and reporting cutoffs belong to each source and can differ. Partial November 2026 turnout is actual observed early participation through its displayed cutoff, not survey turnout and not completed turnout. Equal-progress historical early snapshots have not been established. Do not interpret a partial-to-final comparison as an election forecast.
Implementation: atlas/dist/atlas-analysis.mjs, comparison-data.mjs, parish-names.mjs and source catalogs in atlas/dist/data/.
Reproducing and changing the map
Run npm ci --ignore-scripts, npm run check, then npm run build. The repository includes the reviewed public aggregate snapshot needed to render the map. No private database credential is required to run it.
atlas/data-release.json identifies and hashes every aggregate source file and retains the catalogs' cutoff metadata. deployment.json in a built release identifies the canonical code commit, methodology version and data snapshot. Its capture time is not the source reporting cutoff.
Changes to a formula must update the implementation, this document and the relevant checks together. New data requires a separately reviewed aggregate export and updated source dates and manifest. Older private import scripts are evidence of prior processing, not a clean automated rebuild of every historical database source. See the repository's docs/MAP_DATA_UPDATES.md and docs/MAP_PUBLISHING.md for those operational steps.
The reviewed public aggregate snapshot is preserved as atlas/public-data.tar.gz, with every expanded file and its SHA-256 listed in atlas/data-release.json. Checks and builds verify and expand it automatically into the ignored atlas/dist/data/ directory on a fresh checkout. This keeps thousands of generated JSON files out of ordinary code-review diffs. Node 22+, Git and the standard tar command are required; publishing also uses Python 3. No raw voter archive is included.
Test election scenarios
The three synthetic elections are US Senate 2026 - Demo 1, US Senate 2026 - Demo 2 and US Senate 2026 - Demo 3. Their IDs are demo-2026-1, demo-2026-2 and demo-2026-3. They are test models, not official 2026 observations or forecasts. Select the demos from the regular election dropdown; there is no separate test-election panel. All three expose turnout/composition under Whole Election and Early Vote. Demos 1 and 2 also replay their referenced historical candidate and party returns, including Election Day precinct returns where available. Candidate names, third-party votes and all-valid-vote denominators remain those of the referenced election; no two-party normalization or fictional candidate votes are introduced. Arrow volume baselines retain the underlying historical date. Demo 3 candidate results, support slippage and break-even markers remain unfinished.
Demo 1 exactly replays the official November 5, 2024 participant counts, racial and registered-party margins, parish/precinct distribution and dated registration denominator. Demo 2 exactly replays the November 16, 2019 Edwards–Rispone gubernatorial runoff on the same terms. The user confirmed 2019; there was no 2023 gubernatorial runoff. These replays retain historical registration counts, rather than silently treating them as current 2026 denominators. Participant counts include people who left the modeled contest blank; they are not valid candidate-vote totals.
Demo 3 starts with the official early/absentee snapshot through October 28, 2026: 524,346 participants in 64 parishes. Its initial illustrative settings are total participation 1,700,000 and composition shift 50%. Parameters are retained in the comparison URL (scenarioTurnout, scenarioShift) and CSV; no separate controls panel is shown. This is a hypothetical scenario, not an estimated probability or a newly adopted poll result.
Let E be the observed statewide early total, N = modeled total − E, e_pg the observed early count for parish p and group g, h_pg the corresponding 2022 Election Day count, and H the statewide 2022 Election Day total. Before registration constraints, the remaining count is:
remainder_pg = N × [(1 − shift) × e_pg / E + shift × h_pg / H]
Thus the shift affects parish geography and each parish's racial and party composition together. At zero shift, the unconstrained remainder has the observed early mix; at full shift it has the 2022 Election Day mix. The reference Election Day counts are whole-election participation minus final early/absentee participation within each parish and group. Missing cells are not assumed zero. The model does not describe the known early voters as a representative random sample of the eventual electorate.
Current October 1, 2026 registrations constrain Demo 3. First distribute the remaining total over parishes under each parish's remaining registered-population capacity. Then distribute each parish's remaining racial and party margins under the corresponding group capacities. Saturated cells spill into remaining capacity in proportion to the requested weights; a zero-weight cell is used only when positive-weight capacity is exhausted. This preserves the requested statewide total and every observed early count while preventing any modeled group from exceeding registrations. Capacity adjustments can change the unconstrained mixture; their cell count is reported. The starting settings require a small registered-party adjustment in East Carroll. Fractional counts are expectations and are rounded only for display; downloads retain the modeled values.
Early, remainder and whole-election counts reconcile. Race categories and registered-party categories each sum to the same total; they are separate margins, not a fabricated race-by-party cross-tab. Registered party is not candidate preference. Age distributions and historical joint demographic distributions are not yet modeled in these demos.
The remainder includes any voting after the snapshot cutoff, including unreported later early or absentee votes. It is therefore not labeled observed Election Day participation. Demo 3 is initially parish-only: no new 2022-to-2026 precinct crosswalk or local composition allocation is fabricated. Historical replays retain reported precinct codes and existing warnings that historical boundary equivalence is unverified. Demo 3 candidate results and unsupported precinct/method combinations remain unavailable.
Implementation: atlas/dist/scenarios.mjs; checks: atlas/tests/scenarios.mjs. Model definitions are versioned with source code; the existing 6,230-file source snapshot is unchanged. Changes to turnout assumptions do not rewrite official elections, survey responses or frozen survey weights.