Converting Election Markup Language (EML) to csv

Note that the map above isn’t really a good illustration here because I used a different data source to create it.

Getting results of Dutch elections at the municipality level can be complicated, but what if you want to dig a little deeper and look at results per polling station? Or even per candidate, per polling station? For elections since 2009, that information is available from the data portal of the Dutch government.


The data is in Election Markup Language, an international standard for election data. I didn’t know that format and processing the data posed a bit of a challenge. I couldn’t find a simple explanation of the data structure, and the Electoral Board states that it doesn’t provide support on the format.

For example, how do you connect a candidate ID to their name and other details? I think you need to identify the Kieskring (district) by the contest name of the results file. Then, find the candidate list for the Kieskring and look up the candidate’s details using their candidate ID and affiliation. But with municipal elections, you have to look up candidates in the city’s candidate list (which doesn’t seem to have a contest name).

Practical tips

If you plan to use the data, here are some practical tips:

  • Keep in mind that locations and names of polling stations may change between elections.
  • If you want to geocode the polling stations, the easiest way is to use the postcode, which is often added to the polling station name (only for recent elections). If the postcode is not available or if you need a more precise location, the lists of polling station names and locations provided by Open State (2017, 2018) may be of use. Use fuzzy matching to match on polling station name, or perhaps you could also match on postcode if available. Of course, such an approach is not entirely error-free.

Further, note that the data for the 2017 Lower House election is only available in EML format for some of the municipalities. I guess this has something to do with the fact that prior to the election, vulnerabilities had been discovered in software to count the votes, so they had to count the votes manually.

Python script

Here’s a Python script that converts EML files to csv. See caveats there.

UPDATE 23 February 2019 - improved version of the script here.

The orientation of Amsterdam’s streets

Eight days from now, Amsterdam will have a new metro line traversing the city from north to south. But what about the orientation of the city’s streets?

Geoff Boeing - who created a Python package for analysing street networks using data from OpenStreetMap - just published a series of polar histograms of American and ‘world’ cities. Amsterdam isn’t among them, but Boeing made his code available, so I used that to create charts for the largest cities in the Netherlands.

While the pattern isn’t nearly as monotonous as in most American cities, I’m still surprised how many streets in Amsterdam run from north to south or from east to west. The Hague has a strong diagonal orientation; Rotterdam doesn’t seem to have a dominant orientation and Utrecht is a bit in between.

With Boeing’s code, you can also do the analysis specifically for roads that are accessible to cyclists, but for Amsterdam that doesn’t make much difference since most roads are.


15 July 2018 - There was some really interesting discussion on Twitter in response to my post from last Friday (I use Twitter names to refer to people; most sources are in Dutch).

Curved streets

Both Sanne and Egon Willighagen asked how the chart treats curved streets. I have to admit I hadn’t checked, but the docstring of the add_ege_bearings function explains that it calculates the compass bearing of edges from origin node to destination node, so that implies that streets are treated as if they were straight lines.

Is that a problem? Probably not for many US cities, for they seem to have few curved streets. As for Amsterdam: most people’s mental image of the city is probably dominated by the curved canals of the city centre. However, many neighbourhoods consist of grids of more or less straight streets. So perhaps curved streets have little impact on the analysis after all.

Length versus surface

Hans Wisbrun argues that the chart type is nice, but also deceptive. The number of streets is represented by the length of the wedges, but one may intuitively look at the surface, which increases with the square of the length. In a post from 2013 (based on a tip from Ionica Smeets), he used a chart by Florence Nightingale to discuss the problem.

Rogier Brussee agrees, but argues that a polar chart is still the right choice here, because what you want to show is the angle of streets.

In a more general sense, I think the charts are an exploratory tool that’ll give you an idea how street patterns differ between cities. If you really want to understand what the wedges represent, you’ll have to look at a map.

Beach ridges

That’s what Stephan Okhuijsen did. He noted that the chart for The Hague appears to reflect the orientation of the city’s coastline. Not quite, Christiaan Jacobs replied. The orientation of the city’s streets is not determined by the current coastline, but by the original beach ridges.

I don’t know much about geography (or about The Hague for that matter), but a bit of googling suggests Jacobs is right. See for example this map (from this detailed analysis of one of The Hague’s streets), with the old sand dunes shown in dark yellow.

See also links to previous similar work in this post by Nathan Yau (FlowingData).

Gentrificatie in kaart gebracht

De kaartmakers van de gemeente Amsterdam hebben een kaart gemaakt waarop je de Buurtstraatquote (BSQ) ziet. De BSQ speelt een centrale rol bij de hervorming van de erfpacht, waarmee het sociale grondbeleid van de gemeente wordt uitgehold - maar daar gaat dit artikel niet over. Voor nu ben ik geïnteresseerd in de BSQ als graadmeter voor grondwaarden.

Zoals de gemeente samenvat, zijn «de hoge BSQ’s te vinden in de gewilde locaties in de stad en de lage BSQ’s in de minder gewilde locaties in de stad». De grachtengordel en de omgeving van het Vondelpark hebben hoge BSQ’s; lage BSQ’s zijn te vinden zijn in Zuidoost, Nieuw-West en Noord. Dat viel te verwachten.

Interessanter is de verandering van de BSQ. De gemeente heeft cijfers beschikbaar gesteld over duizenden straten of straatsegmenten, voor de jaren 2014 en 2016. Dat is natuurlijk een korte periode en je kan er niet zomaar van uitgaan dat deze periode representatief is voor lange-termijntrends. Even goed geven de cijfers een interessant beeld.

De grafiek hieronder toont de verdeling van BSQ’s voor meergezinswoningen in 2014 en 2016.

De piek is naar rechts verschoven en de mediaan is gestegen van 28 naar 38. Om politieke redenen is bepaald dat de BSQ nooit lager dan 5 of hoger dan 49 kan zijn, wat verklaart waarom zoveel straten een BSQ van 5 of 49 hebben. Dit impliceert dat de toename van de BSQ waarschijnlijk geen volledig beeld geeft van de stijging van de grondprijzen.

Op de kaart hieronder zie je de ontwikkeling van de BSQ voor meergezinswoningen in verschillende delen van de stad. Straten waar grote veranderingen misschien geflatteerd zijn door de onder- en bovengrens van de BSQ heb ik weggelaten. Dat geldt voor straten die al in de buurt van de maximale BSQ zaten, met name de Grachtengordel en delen van Zuid. Het geldt ook voor straten, vooral in Zuidoost, waar de BSQ in de buurt van de ondergrens van 5 is gebleven.

Rood betekent dat de BSQ met tenminste de helft is toegenomen; oranje een stijging met minder dan de helft en groen dat de BSQ is gedaald. Er zijn enkele rode gebieden buiten de ring: met name IJburg, bepaalde delen van Nieuw-West en Buitenveldert. Buitenveldert grenst aan de Zuidas en heeft te maken met instroom van expats en studenten.

Binnen de ring stijgt de BSQ in gebieden die vaak worden geassocieerd met gentrificatie, zoals de Kolenkit in West, de Vogelbuurt in Noord en de Indische Buurt in Oost. Verassender is Betondorp, een buurt met lage inkomens waar veel ouderen wonen. In 2015 werd deze buurt nog omschreven als «een van de weinige wijken in Amsterdam waar de oprukkende gentrificatie nog niet heeft toegeslagen». Als de BSQ een graadmeter is, dan zou dat wel eens kunnen veranderen.

Voor methode en technische details, zie de Engelstalige versie van dit artikel.

Gentrification mapped

The map makers of the City of Amsterdam have created a map that shows the Neighbourhood Street Quota or BSQ. The BSQ plays a key role in a highly controversial reform that is eroding the city’s social ground lease policy, but that’s not the topic of this article. For now, I’m interested in the BSQ as an indicator of land value.

As the city government puts it, «the high BSQs are found at popular locations in the city and the low BSQs at less popular locations in the city» (for details see Method, below). Unsurprisingly, the centrally located Centrum and Zuid districts have high BSQs and the peripheral areas have low BSQs.

More interesting is how the BSQ has changed. The city government has provided data for thousands of streets or street segments, for 2014 and 2016. Of course, this is a short time period and the patterns may or may not reflect longer-term developments.

The chart below shows the distribution of BSQs for flats (as opposed to single-family dwellings) for 2014 and 2016.

The peak has moved to the right, as the median value has risen from 28 to 38. For political reasons, the BSQ can never be lower than 5 or higher than 49, which explains the large number of streets with a value of 5 or 49. This implies that rises in BSQ don’t fully reflect how much land values have risen.

The map below shows how much BSQs for flats have risen in different parts of Amsterdam. I omitted streets with low or high BSQs where substantial changes in BSQ may have been hidden by the upper and lower limits. At the high end, this applies to the Canal Belt and much of the Zuid District. At the lower end, this applies to many peripheral areas including almost the entire Zuidoost District.

Red streets indicate an increase of the BSQ by more than a half; orange streets an increase by less than a half and the rare green streets a decrease of the BSQ. There are some red areas outside the ring road: mainly the IJburg expansion to the east; some parts of Nieuw-West; and Buitenveldert. Buitenveldert is a neighbourhood south of the Zuidas business district with a growing number expats and students among its residents.

Within the ring road, BSQs are rising in areas that are often associated with gentrification, such as the Kolenkit in West, the Vogelbuurt in Noord and the Indische Buurt in Oost. Perhaps more surprising is Betondorp, a low-income area with many older residents, described in 2015 as «one of the few neighbourhoods in Amsterdam not yet affected by the advance of gentrification». If the BSQ is an indication, that may be about to change.


A list (pdf) of BSQs for 2016 and 2014 was recently sent to the city council. The BSQs are referred to as 2018 and 2017, but are based on data from 2016 and 2014 respectively (or to be more precise: the ‘2017 BSQ’ uses data from 2015 or 2014, whichever is lowest). The map created by the City of Amsterdam uses the ‘2017 BSQ’.

For each house, the municipality calculates an individual land quota using the formula: land value / (land value + theoretical cost of rebuilding the house). The land value is obtained by subtracting the rebuilding cost from the total value of the house (WOZ).

Subsequently, BSQs are calculated as the average land quota per street (or street segment if a street traverses multiple neighbourhoods). This is done separately for single-family dwellings and flats.

The interpretation of the BSQ is a bit tricky: one should expect higher land values to be reflected in higher BSQs, but the exact relationship will depend on the value of the building and whether that also responds to changes in land value (for example, because more expensive materials are used).

In my analysis, I only used BSQs for flats, and only the streets or street segments for which a BSQ is available for both 2014 and 2016 (thus excluding new urban expansions).

For the map, I also excluded streets where an increase of the BSQ by less than half may be hidden by the lower or upper limit of the BSQ: those with a 2014 value of 5 and a 2016 value of less than 8; and those with a 2014 value above 32 and a 2016 value of 49.

In creating the map I also ignored long streets that traverse multiple neighbourhoods and that therefore have been separated into multiple segments. Constructing street segments from line geometries representing the entire street seemed like a lot of work (perhaps there’s a simple way to do this, but I couldn’t find it).

I used Tabula to extract data from the original pdf; this Python script to process the data, create a csv for the chart and create a shapefile for the map; D3.js for the chart and Qgis to create the map (using Open Street Map map data and Stamen Toner Lite for the background).

Nekt Strava de Fietstelweek?

Strava is een populaire app om fietsritten mee op te nemen. Het bedrijf probeert al een paar jaar om zijn gegevens aan lokale overheden te verkopen zodat die ze kunnen gebruiken bij hun fietsbeleid. NDW, een platform van overheden waaronder Amsterdam, heeft zes maanden aan Stravagegevens gekocht om eens uit te proberen wat je hiermee kan.

De overstap naar Strava betekent mogelijk het einde van de Fietstelweek, een jaarlijkse actie om fietsgegevens te verzamelen waar duizenden vrijwilligers aan meedoen. Ik heb de gegevens van de Fietstelweek ooit gebruikt om te analyseren hoe lang je moet wachten bij stoplichten. De Fietstelweek kreeg geld van dezelfde overheden die nu experimenteren met gegevens van Strava.

Eén van de redenen waarom overheden naar alternatieven kijken is dat de Fietstelweek minder deelnemers heeft dan ze graag zouden willen. Daar zit iets in. Neem bijvoorbeeld de onderstaande kaart, met fietsroutes van en naar Amsterdam Centraal Station.

Op zich een interessante kaart. Niet heel verassend is de intensiteit het hoogst in de buurt van fietsenstallingen. De Geldersekade (met de soms chaotische kruising met de Prins Hendrikkade) en de Piet Heinkade lijken belangrijke toegangswegen te zijn. Het lijkt erop dat mensen die met de fiets naar CS gaan wat vaker in het oosten van de stad wonen.

Maar let op: het gaat om kleine aantallen. Zelfs de drukste segmenten vertegenwoordigen niet meer dan 40 ritten. Eén loyale deelnemer aan de Fietstelweek zou letterlijk de kaart kunnen veranderen door de hele week haar fietsrit naar werk op te slaan.

Strava beschikt over veel grotere datasets, maar deze gegevens roepen weer andere vragen op. Strava noemt zich ‘het sociale netwerk voor sporters’ en wil weten of je een racefiets, een mountainbike, een tijdritfiets of een cyclocrossfiets gebruikt (‘anders’ is geen optie). Is Strava wel representatief voor mensen die bijvoorbeeld op hun stadsfiets naar werk gaan?

Het antwoord van Strava op dit soort vragen is dat ze proberen om competitie minder centraal te stellen en hun app socialer te maken, met Facebook-achtige tools. Op die manier hopen ze meer gegevens te verzamelen over ‘normale’ fietsritten Ze zeggen ook dat mensen met de app vaak dezelfde routes rijden als andere fietsers, vooral in de steden.

Maar klopt dat wel? De Strava heatmap (kies rood en rides) voor Amsterdam zou je misschien kunnen interpreteren als een combinatie van recreatieve routes (Vondelpark, Amstel) en fietsers die zo snel mogelijk de stad in of uit proberen te rijden (plus flink wat mensen die hun rondjes op de Jaap Edenbaan hebben opgeslagen als fietstochten).

Misschien valt er een manier te bedenken om de recreatieve en sportieve ritten eruit te filteren en hou je dan nog genoeg ‘normale’ fietsritten over. Aan de andere kant, bijna driekwart van de fietsritten in Nederland is korter dan 3,7 km, en ik vermoed dat zulke korte ritjes zelden op Strava worden gezet.

Er is ook nog een sociaal-economisch aspect. Er is aangevoerd dat Strava vooral wordt gebruikt door mensen die in de rijkere buurten wonen, terwijl andere buurten misschien wel meer behoefte hebben aan betere fietsinfrastructuur.

Natuurlijk is het fietsgebruik sowieso ongelijk verdeeld, en dat zie je ook terug in de gegevens van de Fietstelweek. De kaart hieronder toont de start- en eindpunten van fietsritten in Amsterdam.

De dichtheid is het grootst in het gebied binnen de ring ten zuiden van het IJ. Het aantal fietstochten per 1.000 inwoners correleert ook met woningwaarde: veel fietstochten beginnen of eindigen in rijkere buurten. Zoals gezegd, dit weerspiegelt waarschijnlijk het werkelijke fietsgebruik en wijst dus niet op een probleem met de gegevens.

Om samen te vatten: de Fietstelweek heeft kleinere aantallen deelnemers dan je zou willen, terwijl de gegevens van Strava vragen oproepen over de representativiteit. Strava zou natuurlijk kunnen helpen om die vragen te beantwoorden door een deel van de Amsterdamse gegevens beschikbaar te stellen als open data.

Dit Python-script laat zien hoe de analyse is uitgevoerd.