Skip to content

kaduvan/electoral-analytics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ—³οΈ Tamil Nadu 2026 Election β€” Village-Level Electoral Heatmap

Election data belongs to the people. This project is one step toward making it truly accessible.

The Election Commission of India publishes results as PDFs β€” opaque, unsearchable, and impossible to analyze at scale. We believe that public data should be public: open, structured, visual, and free. This project transforms official ECI Form 20 data into an interactive, village-level analytics platform that anyone can explore β€” no data science degree required.

If you believe in electoral transparency, open government data, and civic empowerment β€” this is for you.

License Python Status


🌟 What This Is

An open-source, interactive village-level electoral analytics platform for the 2026 Tamil Nadu Legislative Assembly Election, visualizing voting patterns across 9,809 villages in 234 Assembly Constituencies.

Key question this answers: How did each village in Tamil Nadu vote in the 2026 Assembly Election?


πŸ“– How to Use

Getting Started

  1. Open the heatmap β€” Simply open site/tn_heatmap_v2.html in a modern browser (Chrome recommended)
  2. Wait for load β€” The file is ~39.5 MB (all data is embedded). First load takes 10–30 seconds
  3. Explore! β€” The page has two main areas: the interactive map (left) and the analytics panel (right)

πŸ’‘ Tip: For best performance, serve locally: cd site && python -m http.server 8000, then open http://localhost:8000/tn_heatmap_v2.html


πŸ—ΊοΈ The Map (Left Side)

Coloring Modes

Use the 🎨 Mode control panel (top-left of the map) to switch between:

Mode What It Shows
Winner + Margin (default) Village color = winning party. Intensity shows margin strength (dark = landslide, light = close fight)
Vote Blend Village color = a blend of all parties' vote shares. Shows multi-party competition visually
Alliance Village color = alliance (TVK, SPA, NDA, NTK, Others). Aggregates coalition performance
None No village shading β€” useful for viewing AC boundaries clearly

Map Controls

  • AC Bounds checkbox β€” Show/hide constituency boundary lines (dashed)
  • AC Labels checkbox β€” Show/hide constituency number/name labels
  • Legend (bottom-left) β€” Shows party colors with village counts. Click any party to dim it on the map. Click again to restore. Expand/collapse with the β–Ό button.

Map Interactions

  • πŸ–±οΈ Click any village β€” Opens a detail panel on the right showing:
    • Village name, district, AC number
    • Full candidate-wise vote breakdown with horizontal bar charts
    • Winner, runner-up, and margin
    • Total valid votes
  • πŸ” Search (top bar) β€” Type a village name, district, or AC number to find and zoom to it
  • Zoom/Pan β€” Standard Leaflet map controls (scroll wheel, drag, double-click to zoom)
  • β–Έ/β—‚ Toggle button β€” Collapse or expand the right analytics panel

AC Boundary Overlay

  • Dashed lines show constituency boundaries (dissolved from village polygons)
  • Click any AC label on the map to zoom directly to that constituency

πŸ“Š The Analytics Panel (Right Side)

The right panel has 10 tabs with different analytical views:

1. Overview

At-a-glance summary cards:

  • Total villages, ACs, booths, and vote counts
  • Party wins breakdown (village-level and AC-level)
  • Alliance performance summary
  • Key stats at a glance

2. Positions (Position Analysis)

How many villages did each party come in 1st, 2nd, 3rd, or 4th+ place?

  • Table showing position breakdown per party
  • Filter by position (1st only, 2nd only, etc.)
  • Bar visualization of party strength across all position tiers
  • Use this to find parties that are strong runner-ups but rarely win

3. Districts (District View)

  • Table of all districts ranked by number of villages
  • Shows top 3 winning parties per district with village counts
  • Party-wise breakdown by district

4. AC Dive (AC Deep Dive)

Select any constituency for village-level breakdown:

  • Dropdown to pick any AC (1–234)
  • Shows: AC winner, margin, total votes, number of villages
  • Table of all villages in that AC ranked by winner's vote share
  • Each village shows: winner party, votes, margin percentage

5. Close (Close Contests)

Find the razor-thin village-level battles:

  • Filter by margin threshold: <5%, <10%, <15%, <20%
  • Table of villages where winner and runner-up were separated by tiny margins
  • Sorted by margin (smallest first)
  • These are the "every vote counts" villages

6. Alliance (Alliance View)

Aggregate performance by coalition:

  • Alliance summary cards (TVK, SPA, NDA, NTK, Others)
  • Position breakdown per alliance (1st/2nd/3rd across villages)
  • Alliance strength by district β€” where each coalition dominates

7. Penetration (Party Penetration)

How deep does each party's support run?

  • Threshold filter: Show villages where a party crossed 10%, 15%, 20%, 25%, or 30% of votes
  • Table showing: for each party, how many villages it crossed the threshold in
  • Ranked by number of villages at each penetration level
  • Use this to measure a party's grassroots presence beyond just wins

8. Coverage (Coverage & Quality)

Data quality and completeness:

  • Contest classification: Safe / Comfortable / Close / Very Close / Tie
  • Booth coverage by AC β€” how many villages have data vs total
  • Identifies ACs with low village coverage

9. Top/Bottom (Top & Bottom Villages)

Extreme village-level statistics:

  • Closest Margins β€” Photo finishes (smallest win margins)
  • Biggest Blowouts β€” Most lopsided victories
  • Most Booths β€” Villages with the most polling stations
  • Highest Votes β€” Villages with the highest total vote counts

10. Compare (AC Comparison)

Side-by-side comparison of two constituencies:

  • Select AC 1 and AC 2 from dropdowns
  • Shows: winner comparison, margin comparison, total votes
  • Party-wise village position breakdown for both ACs
  • Great for comparing similar or neighboring constituencies

πŸ“± The Analytics-Only Page

The repo also includes site/tn_analytics.html β€” a standalone analytics dashboard (no map) with all the same tab features. Useful for:

  • Slower machines that struggle with the 39.5 MB heatmap
  • Quick analytics without loading the map
  • Embedded analytics in other pages

πŸ“Š Data Coverage & Transparency

We believe in radical transparency about what our data covers β€” and what it doesn't.

Constituency Coverage

Metric Value
Total ACs in Tamil Nadu 234
ACs with Form20 data 218 (93.2%)
ACs with station-level votes 218
ACs with electors data 206 (88.0%)
ACs entirely missing 16 (6.8%)

Vote Coverage vs Official Totals

Metric Our Data (218 ACs) Gap Notes
Registered electors 5.03 Cr ~1.83 Cr missing We cover ~73% of TN's ~6.86 Cr electors
Station-level valid votes 4.27 Cr (42,662,846) β€” This is the figure shown on the heatmap
AC-level valid votes 3.72 Cr (37,190,300) β€” Includes EVM + postal at AC level
Polling stations 71,639 β€” With candidate-wise vote breakdowns
Estimated turnout (covered ACs) ~74% β€” Based on AC-level totals
Estimated missing votes ~1.5–2 Cr From 16 missing ACs + 12 partial ACs These votes are invisible on our map

⚠️ What this means: The heatmap shows 4.27 Cr valid votes from 218 ACs. The official Tamil Nadu total includes all 234 ACs with approximately 6.86 Cr registered electors. Our map does not represent roughly 28 ACs worth of votes (16 entirely missing + 12 with partial data). This is approximately 25–27% of Tamil Nadu's electorate that is invisible on the map.

Village-Level Mapping

Metric Value
Total village polygons 18,165 (Survey of India Census 2011)
Villages with matched data 9,809
Stations matched to villages 65,717 / 68,890 (92.0%)
Unmatched stations 3,173 (4.6%) β€” mostly urban or name-mismatch

Missing Constituencies

Region Missing ACs Count Likely District
Perambalur AC147 1 Perambalur
Cuddalore/Ariyalur AC151–AC159 9 Cuddalore, Ariyalur
Thanjavur/Pudukkottai AC178–AC183 6 Thanjavur, Pudukkottai

Additionally, 12 ACs (AC027, AC030, AC031, AC034, AC035, AC054, AC229–AC234) have station-level vote data but no electors/turnout data at the AC level.

These constituencies appear as grey/empty on the heatmap.


⚠️ Methodology & Limitations

How Village-Level Votes Are Estimated

Form20 PDF β†’ Station-level votes β†’ Name-matching β†’ Village assignment β†’ Heatmap
  1. Form20 Parsing: Official ECI Form20 PDFs are parsed to extract station-level vote counts for each candidate
  2. Name Matching: Polling station names are matched to village names from Survey of India boundary data
  3. Vote Assignment: Station votes are assigned to the matched village
  4. Aggregation: If multiple stations match a village, their votes are summed
  5. Visualization: The resulting village-level data is color-coded and rendered on the map

Known Limitations

  1. Station-to-Village Matching (65.6%): Only 45,193 of 68,890 stations could be matched. Unmatched stations are in urban areas or have naming discrepancies. Their votes are not represented on the map. The map understates actual votes in many villages.

  2. Village Boundaries Are Approximate: Survey of India polygons (Census 2011) may not align with actual polling booth service areas. A single station may serve multiple villages β€” all votes are assigned to one village.

  3. No Official Village-Level Data: The ECI does not publish village-level results. Our village vote counts are estimates derived from station-level data. They should not be cited as official figures.

  4. Missing 28 ACs: 16 ACs have zero Form20 data. 12 more lack electors/turnout data. Any statewide analysis is incomplete.

  5. Candidate Name Variations: Names parsed from PDFs may have minor spelling inconsistencies.

  6. AC Boundaries: Dissolved from village polygons, not from official delimitation shapefiles. May have slight inaccuracies.

  7. No Postal Votes in Map: Station-level data is EVM only. Postal votes (typically 1–2% of total) are not distributed to villages.

  8. Large File Size: ~39.5 MB HTML with embedded GeoJSON. Slow on mobile or weak connections.


πŸ› οΈ Tech Stack

Component Technology
Map Rendering Leaflet.js 1.9.4
Basemap CARTO Positron (light tiles)
GeoJSON Processing Shapely (Python)
Data Pipeline Python 3.12
Boundary Data Survey of India Village Census 2011
Election Data ECI Form 20 (Official Results)
Output Format Single self-contained HTML file

πŸ“ Project Structure

electoral-v4/
β”œβ”€β”€ site/
β”‚   β”œβ”€β”€ tn_heatmap_v2.html       # πŸ—ΊοΈ Main deliverable (39.5 MB, self-contained)
β”‚   └── tn_analytics.html        # πŸ“Š Analytics-only dashboard (no map)
β”œβ”€β”€ scripts/
β”‚   └── 14_build_v2.py           # Build pipeline (Python, ~2300 lines)
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ form20_raw.json          # Parsed Form20 election data (218 ACs) [gitignored]
β”‚   β”œβ”€β”€ wiki_results.json        # Wikipedia-sourced AC results (234 ACs)
β”‚   └── wiki_candidates.json     # Wikipedia-sourced candidate lists
β”œβ”€β”€ booth/                        # Booth structure data (234 AC JSONs) [gitignored]
β”œβ”€β”€ form20-pdf/                   # Original Form20 PDFs [gitignored]
β”œβ”€β”€ TAMIL NADU_VILLAGES.geojson   # Village boundary data (93 MB) [gitignored]
└── README.md

πŸš€ Quick Start

Option 1: Just Open the HTML

# Simply open in a browser (Chrome recommended)
start site/tn_heatmap_v2.html        # Windows
open site/tn_heatmap_v2.html         # macOS
xdg-open site/tn_heatmap_v2.html     # Linux

⚠️ The file is ~39.5 MB. First load may take 10–30 seconds.

Option 2: Serve Locally (Recommended)

cd site
python -m http.server 8000
# Open http://localhost:8000/tn_heatmap_v2.html

Option 3: Rebuild from Source

# Prerequisites: Python 3.12+, shapely
pip install shapely

# Run the build pipeline
python scripts/14_build_v2.py

# Output: site/tn_heatmap_v2.html

🎨 Party Colors & Alliances

Party Abbrev Color Alliance
Tamilaga Vettri Kazhagam TVK 🟒 Dark Green TVK (Standalone)
Dravida Munnetra Kazhagam DMK πŸ”΄ Red Secular Progressive Alliance (SPA)
Indian National Congress INC πŸ”΅ Sky Blue SPA
Desiya Murpokku Dravida Kazhagam DMDK οΏ½ Medium Purple SPA (Secular Progressive Alliance)
Viduthalai Chiruthaigal Katchi VCK 🟣 Purple SPA
Communist Party of India CPI πŸŸ₯ Dark Red SPA
Communist Party of India (Marxist) CPI(M) πŸŸ₯ Crimson SPA
Indian Union Muslim League IUML 🟩 Forest Green SPA
All India Anna Dravida Munnetra Kazhagam AIADMK 🟠 Orange NDA
Bharatiya Janata Party BJP 🟀 Dark Orange NDA
Pattali Makkal Katchi PMK 🟑 Gold NDA
Amma Makkal Munnetra Kazhagam AMMK 🍫 Chocolate NDA
Naam Tamilar Katchi NTK πŸ”· Royal Blue NTK (Standalone)
Other parties / Independents IND/Others βšͺ Grey β€”

πŸ“– Data Sources

Source Description License
Election Commission of India Form 20 (official constituency-wise results) Public government data
Survey of India Village boundary polygons (Census 2011) Government open data
Wikipedia AC-level results, candidate lists CC-BY-SA
Booth-level mapping Polling station to village name mapping Crowd-sourced

πŸ”¬ Build Pipeline Details

The build pipeline (scripts/14_build_v2.py, ~2300 lines) performs:

  1. Load booth data (234 AC files with polling station structure)
  2. Load Form20 data (218 ACs with station-level vote counts)
  3. Load village GeoJSON (93 MB boundary file, 18,165 villages)
  4. Name-match stations to villages (exact string matching on village names)
  5. Distribute votes from stations to matched villages
  6. Dissolve village polygons into AC boundaries (using Shapely)
  7. Generate analytics (party positions, alliance data, district summaries)
  8. Optimize GeoJSON (round coordinates to 5 decimal places β†’ 40% size reduction)
  9. Output single HTML with all data embedded (CSS + JS + GeoJSON inline)

Build time: ~3–5 minutes (primarily I/O bound on the 93 MB GeoJSON)


🀝 Contributing

Contributions are welcome! Areas of particular interest:

  • Missing Form20 data: If you have Form20 PDFs for the 16 missing ACs (AC147, AC151–159, AC178–183), please open an issue or PR
  • Better village matching: Improved station-to-village name matching algorithms (fuzzy matching, geospatial proximity)
  • Performance optimization: Reduce the 39.5 MB output size (tiling, lazy loading, compression)
  • Additional visualizations: New map layers, chart types, or analytical views
  • Mobile responsiveness: The current layout is optimized for desktop
  • Accessibility: Screen reader support, keyboard navigation, high-contrast mode

πŸ“„ License

This project is for educational and research purposes only.

  • Election data: Sourced from Election Commission of India (Form 20), which is public government data
  • Boundary data: Survey of India village boundaries, Government of India open data
  • Code: MIT License

⚠️ IMPORTANT: Methodology & Data Disclaimer

This is an independent, non-official visualization of publicly available election data. It is NOT affiliated with or endorsed by the Election Commission of India (ECI).

1. Indicative, not definitive. Village-level vote estimates are derived by mapping polling station data to village boundaries using name-matching algorithms. These estimates are indicative only and should NOT be treated as official ECI figures. Official results are published only at the constituency (AC) level by the ECI.

2. Booth clubbing affects accuracy. Multiple polling stations are often grouped (clubbed) under a single station name or mapped to the same village. Where clubbing occurs, votes are attributed to the matched village but may not precisely reflect that village's actual voting pattern. Direct village-to-village comparisons may not be accurate.

3. Name-matching is imperfect. Station-to-village matching uses string-based name comparison. Variations in spelling (English transliteration of Tamil names), abbreviated names, and urban station naming conventions cause ~4.6% of stations to remain unmatched. Matched results may also contain errors where similar village names exist in the same AC.

4. Candidate coverage is limited. Candidate-level vote data is sourced from Wikipedia, which typically lists only the top 3 candidates per AC (out of an average of ~18 candidates). All remaining candidates' votes are aggregated under "Others." This means:

  • Naam Tamilar Katchi (NTK) votes are largely invisible at the village level, as NTK candidates rarely finish in the top 3 and are not individually tracked in our source data. NTK is a significant party that consistently polls in the range of 3–8% across Tamil Nadu β€” their votes are absorbed into "Others" at the booth/village level.
  • Other smaller parties and most independents similarly have their votes aggregated into "Others."

5. Form20 data gaps. Form20 (station-level) data is available for only 218 of 234 ACs. The remaining ~16 ACs (primarily in Krishnagiri and Dharmapuri districts) have no station-level breakdown β€” only AC-level totals from Wikipedia.

6. Known data quality issues. Approximately 12 ACs have Form20 data that appears incomplete or inconsistent (near-zero vote totals), likely due to PDF parsing errors. These ACs may show misleadingly low vote counts at the village level. Affected ACs include: AC027, AC030–035, AC057–061.

7. Boundary data is from Census 2011. Village boundaries are based on Survey of India Census 2011 data. Boundary changes, new villages, merged villages, or urban reclassification since 2011 are not reflected.

8. Alliance assignments. Alliance groupings (TVK, SPA, NDA, NTK) are based on publicly reported seat-sharing agreements and may not reflect every individual party's formal alliance declaration. Independent candidates (IND) are classified under "Others."

In summary: treat this visualization as an exploratory tool for understanding broad electoral patterns, not as a source of precise vote counts. For official results, always refer to the Election Commission of India.


πŸ™ Acknowledgments

  • Election Commission of India for making Form 20 data publicly available
  • Survey of India for village boundary data
  • Leaflet.js and the open-source mapping community
  • All contributors and data validators
  • Every citizen who believes that public data should be public

Built with ❀️ for electoral transparency and civic empowerment
Because democracy deserves better than PDFs.

About

Interpretation of electoral results of TN election data based on form-20, mapped against respective villages / pincodes / wards for grass root level inference.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors