Stack
About
The 2026 Nice municipal elections saw a major political shift: for the first time, the city’s incumbent centre-right mayor faced a credible far-right challenger from within his own camp. This project maps the full result, round by round, at polling station level across all 252 bureaux de vote, 9 cantons, and 38 quartiers. Built in one evening from official data published on data.gouv.fr.
The story
The 2026 Nice municipal elections were widely covered in the press, and rightly so. The city, one of the largest in France, shifted toward a Rassemblement national coalition for the first time. Seven lists competed in round one. Three reached the second. 252 polling stations, 9 electoral cantons, 38 administrative neighbourhoods.
Most of the commentary, however, stayed at the surface. What the numbers could actually say about the geography of Nice’s electorate was less explored. Nice is a city of stark contrasts: a centrist bourgeois core, the trendy upscale Libération neighbourhood, quiet hillside residential zones, and popular housing estates in the north. Realities that would constitute separate communes elsewhere in France. The data tells a different story in each.
Three questions drove the project. First, the balance of forces within the left bloc, divided between the radical NFP/LFI list and the UNIS ecologist-socialist coalition. Second, the extent of vote transfers toward Christian Estrosi in a bid to block Eric Ciotti. Third, the absence of a unified anti-Eric Ciotti front in round two despite higher turnout.
The source data came from data.gouv.fr, the French government’s open data platform. Two CSV files: one for round one, one for round two. Results were joined to geographic coordinates, enriched with canton attribution from official boundary sources (OpenDataSoft, INSEE, POPSU ArcGIS), and rendered with Folium on OpenStreetMap tiles. The output is a single self-contained HTML file with no backend.
Output
The output is a set of interactive maps hosted at elections.gndar.dev. Results can be explored at three geographic scales: canton, neighbourhood, and polling station. All maps are in French.
Learnings
The first obstacle was a silent data quality issue: polling station codes in the results file used leading zeros, while the coordinates JSON did not. A straightforward join produced no errors and no output. Just missing data. Catching it required comparing record counts at each step rather than trusting the merge.
The geographic data required stitching three boundary sources at different administrative levels. None shared a common identifier with the electoral data. Normalising names and codes across all sources was a prerequisite before any spatial work could begin.
The broader learning applies to any AI-assisted build: the more precise the initial brief, the better the output. Corrections made mid-way are possible but costly. The further into the build, the harder it becomes to adjust structure without a full rewrite. Front-loading clarity is not optional.
This project, data pipeline, geographic joins, interactive map, hosted and live, was built in a single evening, with no prior GIS experience and no background in web development. Claude Code handled the implementation. The work was in knowing what to ask for, and in understanding the data well enough to catch what was wrong.
Why it matters professionally
Civic data projects are a clean environment to practise the full data engineering cycle: raw file parsing, geographic joins, data quality edge cases, and a presentable end output. The same patterns apply directly to pipeline reporting and CRM analytics in B2B contexts. The speed of execution (one evening, zero prior GIS experience) also demonstrates what Claude Code makes possible.