Amsterdam has room for another 2.1 million bicycle racks


Amsterdam has a persistent shortage of bicycle racks. Bicycle professor Marco te Brömmelstroet argues that this is really a matter of making choices: the space occupied by four parked cars could easily accommodate 30 bicycle racks.

Amsterdam is a compact city where space is limited. An important goal of the city administration is to create more room for pedestrians and cyclists, but also for green areas.

It so happens that the city of Amsterdam has recently published open data on on-street parking spaces. The data confirms what we already knew: parking spaces for cars occupy a huge amount of public space. The streets of Amsterdam are littered with as many as 265,225 parking spaces. If you exclude the ones with signs (spaces for charging car batteries; car sharing; etcetera), there are still 260,834 of them.

Assuming that each of them could accomodate at least 8 bicycle racks, there’s room for another 2.1 million bicycle racks. Now you probably wouldn’t want to remove all parking spaces and replace them with bicycle racks, but it does illustrate some of the choices that are available regarding the use of public space.

Map detail here.


The open data on on-street parking spaces is available in WFS format which is meant for creating maps but can also be used for downloading data - here’s a Python script that will do the job. I set the location of the parking spaces to the centre of the surrounding envelope.

I would have liked to display the data on an interactive map using Leaflet and D3js, but I’m afraid the quarter million data points would crash the browser. Instead I used OSM map data in combination with Qgis to display the parking spaces. Unfortunately, this means you can’t zoom in.

As for the parking space to bicycle rack ratio: I’m assuming a typical parking space takes up 12 to 14 m2. Cyclists’ organisation Fietsersbond has calculated that regular bicycle racks take up between 0.84 and 1.18 m2 per bicycle. The city of Amsterdam is a bit more conservative and estimates that a bicycle rack takes up about 1.5 m2, including the room needed to remove the bicycle. This suggests that the number of bicycle racks that could be created per parking space lies somewhere between 8 and 9.3.

Update 3 July 2016 - The city of Nijmegen reckons it can fit as many as 10 bicycle racks on a parking space.
Update 31 January 2017 - And the city of New York needs about nine parking spaces to accomodate 69 city bikes.
And a follow-up (in Dutch).

Assignment 1-3

A little background: I’m using the Outlook on Life Surveys dataset and I’m interested in the relation between union membership and political participation (background here). The third assignment is similar to the second one, only we’re required to do some data management before outputting the data. Therefore, I’ll submit an adapted version of the programme and blogpost of the previous assignment.

The output’s supposed to be ‘interpretable (i.e. organized and labeled)’. For those who are logged in to the course website, I refer to this forum post disucssing how I interpreted this requirement.

In terms of data management, I’ll perform the following steps: first recode ‘refused’ to NaN (not required for the first variable PPWORK, because it has no missing values) and recode the answers to labels (e.g. 1 = ‘Yes’). Next, I’ll create a secondary variable which indicates whether respondents have engaged in any of the four types of political participation discussed below.

The programme itself is posted here. Below I’ll discuss some of the output. For the sake of convenience, I’ll only show percentages (the raw counts can be obtained by running the programme). First, the current employment status of respondents.

PPWORK: Current Employment Status
Not working - retired                           21.011334
Not working - on temporary layoff from a job     1.264167
Not working - looking for work                  10.854403
Not working - disabled                           8.456844
Not working - other                              6.451613
Working - self-employed                          6.190061
Working - as a paid employee                    45.771578
dtype: float64

One of the variables I’m interested in, is union membership. My understanding of the American situation is that union membership is often dependent on whether your workplace is organised (by contrast, in the Netherlands it’s not uncommon for unemployed or retired people to be union members). For that reason, it makes sense to look specifically at respondents who are working as paid employees. (The fact that union membership is measured at the household level complicates matters but that doesn’t change my preference to focus on paid employees.)

1,050 respondents (46%) are paid employees. This would seem to be a sufficiently large group for the purposes of the analyses I plan to do. In the programme, I created at subset of respondents who indicated they are working as paid employees. All output below is based on this subset.

Next, let’s take a look at the numbers for the variable on union membership (as indicated, at the household level).

W1_P8: Does anyone in your household currently belong to a union?
NaN     1.142857
No     78.380952
Yes    20.476190
dtype: float64

Within the subset of respondents with paid employment, little over 20% indicate that at least one person in their household is a union member. This compares to a union density of 11.1% among wage and salary workers in the US according to the Bureau of Labour Statistics.

Some of that difference can be explained by the fact that the 20% figure will include some respondents who aren’t union members themselves but who have someone in their household who is. On the other hand, the BLS is a bit more persistent in assessing union membership, and would likely classify some people as union members who wouldn’t be classified as such in the OOL surveys.[1] All in all, I’m inclined to say the 20% figure in the OOL surveys is higher than expected and that there is a possiblity that the survey sample is in some way biased towards union members.

And finally the political participation measures.

W1_L4_A: [Contacted a public official or agency ] Please indicate if you have done any of the following activities in the last 2 years.
NaN     2.190476
No     74.095238
Yes    23.714286
dtype: float64
W1_L4_B: [Attended a protest meeting or demonstration ] Please indicate if you have done any of the following activites in the last 2 years.
NaN     2.190476
No     90.571429
Yes     7.238095
dtype: float64
W1_L4_C: [Taken part in a neighborhood march ] Please indicate if you have done any of the following activites in the last 2 years.
NaN     2.095238
No     93.047619
Yes     4.857143
dtype: float64
W1_L4_D: [Signed a petition in support of something or against something ] Please indicate if you have done any of the following activites in the last 2 years.
NaN     2.380952
No     58.190476
Yes    39.428571
dtype: float64

Respondents are more likely to have signed a petition or contacted an offical than to have hit the streets. This is as expected.

I’ve created a secondary variable indicating whether respondents have participated in any of the discussed forms of political participation. Respondents who have answered ‘Yes’ to any of the four political participation questions will be assigned a value ‘Yes’; those who have answered ‘No’ to all four questions will be assigned a value ‘No’ and those who have not answered ‘Yes’ to any of the questions but who have refused to answer at least one of the questions will be treated as missing.

ANY: Respondent has engaged in any of the four forms of political participation in the last 2 years
NaN     2.190476
No     50.952381
Yes    46.857143
dtype: float64

The frequency table shows that almost half the respondents have engaged in any of the discussed forms of political participation in the last 2 years.

Finally a word on missing values. For all variables considered here, the percentage ‘refused’ is below 2.5%. This would seem sufficiently low not to expect any problems arising from this.

PS One of the students who reviewed my first assigment suggested I include ‘canvassing’ as a measure of political participation, which seems to make sense. Unfortunately the dataset doesn’t seem to include this aspect, but there are variables on other types of political participation that I may add in the future.

  1. «Employed wage and salary workers are classified as union members if they answer “yes” to the following question: On this job, are you a member of a labor union or of an employee association similar to a union? If the response is “no” to that question, then the interviewer asks a second question: On this job, are you covered by a union or employee association contract? If the response is “yes,” then these persons, along with those who responded “yes” to being union members, are classified as represented by a union. If the response is “no” to both the first and second questions, then they are classified as nonunion.»  ↩

Coursera Data Analysis and Interpretation

I was initially introduced to R by Nathan Yau’s Visualize This, but subsequently I learned a lot about R through some of the courses in Brian Caffo, Roger Peng and Jeff Leek’s Data Science Specialization at Coursera. In fact, the course was a reason for me to postpone switching from R to Python.

By now, I’ve decided to make the switch anyhow, and I think I’ve found another Coursera specialisation that will help me learn the tricks: Lisa Dierker and Jen Rose’s Data Analysis and Interpretation. It’s kind of basic, at least at the beginning, but that’s good. Some of the assignments require you to blog about a project of your choosing, so I’ll be posting about my homework here.

Base versus ggplot2

Yesterday, stats guru Jeff Leek confessed the ultimate unpopular opinion in data science: «I don’t use ggplot2 and I get nervous when other people do» (if you haven’t a clue what this is about, you may want to skip this post altogether). His confession met with ridicule, more riducule, and an occasional «oh my god I thought I was the only one!».

I sort of assumed everybody uses ggplot now. I was wrong: I like base for graphics, is that weird? * Buena referencia para graficas base! (si como yo, odian ggplot). * base graphics FTW re:slopegraph (it’s a royal pain to do this in ggplot). * I’m not a fan of ggplot. * Retro! * I kinda hate ggplot. * Vigorous group discussion on the merits of base plot vs #ggplot in #rstats.

For me, it’s six of one and half a dozen of the other: I’m planning to switch to Python.

Komen stadsdeelpolitici op landelijke TV? Gegevens uit de NPO Backstage API

Laatst heb ik gekeken hoe vaak Amsterdamse politici worden genoemd op de websites van het Parool en AT5. Voorlopige conclusie: de belangstelling voor de stadsdeelpolitiek lijkt te zijn ingezakt sinds de macht van de stadsdelen is ingeperkt per maart 2014.

Toen ik vervolgens een artikel tegenkwam waarin wordt uitgelegd hoe makkelijk je aan gegevens kan komen over NPO-programma’s, heb ik ook nog een blik geworpen op de belangstelling van de publieke omroep voor de Amsterdamse politiek.

Met een slag om de arm (zie hieronder, Methode) zijn de resultaten: in de raadsperiode tot maart 2014 werden gemeentepolitici 28 keer genoemd en stadsdeelpolitici 18 keer. Sinds de hervorming van het bestuurlijke stelsel in maart 2014 werden gemeentepolitici 11 keer genoemd en stadsdeelpolitici nog maar 3 keer (de grafiek toont het gemiddelde aantal vermeldingen per 100 dagen). Dit lijkt dus het beeld te bevestigen dat stadsdeelpolitiek in de ogen van de redacties minder relevant is geworden.

In de periode 2010–2014 zijn de volgende stadsdeelpolitici genoemd (of hun naamgenoten):

  • Fatima Elatik (4 keer): Over Marokkaanse jongeren, lipstick moslims en haar werk als stadsdeelvoorzitter.
  • Henk de Boer (2 keer): Iemand anders met dezelfde naam?
  • Ronald Mauer: Over de dood van een grensrechter in Nieuw-Sloten.
  • Jeroen Mirck: Kwam als internetjournalist aan het woord in een programma over Rutger Castricum.
  • Frans Icke: Over zweefvliegen. Iemand anders met dezelfde naam?
  • Jeroen van Spijk: Over parkeertarieven in Oost (AT5-fragment bij De Wereld Draait Door).
  • Boudewijn Oranje: Over de sloopplannen van de UvA voor het BG-terrein.
  • Jan Engel: Iemand anders met dezelfde naam?
  • Stefan de Bruijn: Over de vluchtkerk (aangekondigd als gemeenteraadslid, maar dat terzijde).
  • Martien Kuitenbrouwer: Naar aanleiding van de juwelier in de Jan Evertsenstraat die werd doodgeschoten bij een overval.
  • Coby van Berkum: Over het dreigende verlies van de PvdA bij de verkiezingen van maart 2014.
  • Ahmed Baâdoud: Over liquidaties.
  • Bart van der Linden: Iemand anders met dezelfde naam?
  • Joël Andoetoe: Over de VVD en de affaire-Van Reij.

En in de huidige periode:

  • Jeroen van Berkel: Iemand anders met dezelfde naam?
  • Frans Icke: Zie hierboven.
  • Alexander Hammelburg: Kwam als politicoloog aan het woord over Saoedisch ingrijpen in Jemen.

In verschillende gevallen lijkt er sprake te zijn van naamgenoten die niets te maken hebben met de stadsdeelpolitiek. Wanneer er daadwerkelijk stadsdeelpolitici op de landelijke TV komen, dan gaat het lang niet altijd over stadsdeelpolitiek. Maar in zijn algemeenheid kan je wel zeggen dat stadsdeelpolitici in de vorige periode vaker werden gezien als relevante bron over wat er speelt in Amsterdam.


Zoeken via de NPO Backstage API is op zich vrij eenvoudig en je hoeft niet eens te registreren (!). Bovendien staan op Github verschillende voorbeelden van Pythoncode die laten zien hoe de API werkt.

Ik stuitte wel op het probleem dat er aanvankelijk veel dubbelingen in m’n zoekresultaten zaten. Dit komt doordat de API verschillende soorten informatie bevat zoals een algemene beschrijving van een programma; een beschrijving van metadata en voor sommige programma’s de tekst van de complete ondertiteling voor slechthorenden.

Ik besloot om te zoeken in de ondertitelingen. Op die manier voorkom je veel dubbelingen en gebruik je een consistente dataset. Tegelijk is het wel zo dat de ondertiteling niet van alle programma’s beschikbaar is. Daardoor mis je bijvoorbeeld het radio-optreden van Rutger Groot Wassink bij de EO, waarin hij zijn boycot van de gemeentelijke nieuwjaarsreceptie toelicht.

Met een zoekopdracht binnen de set ondertitelingen hou je nog steeds dubbelingen over, omdat programma’s soms herhaald worden. Het item met Jeroen Mirck over Rutger Castricum bijvoorbeeld is drie keer uitgezonden. Die uitzendingen hebben allemaal een eigen prid (programma-ID), dus daarmee los je het probleem niet op.

De herhalingen heb ik geprobeerd eruit te filteren op basis van de eerste vijftig karakters van de programmabeschrijving (en vervolgens heb ik van alle bijbehorende uitzenddatums de oudste genomen). Deze methode is niet waterdicht: aan de ene kant kunnen er inconsistenties zitten in de programmabeschrijving en aan de andere kant wordt soms dezelfde omschrijving gebruikt voor alle afleveringen van een serie programma’s. Op die manier kan het gebeuren dat meerdere optredens bij Pauw en Witteman ten onrechte worden geteld als één optreden. Pragmatisch gezien denk ik dat de verstorende werking hiervan minder ernstig is dan wanneer je herhalingen meetelt als afzonderlijke optredens. Maar het blijft een beetje een los eindje.

Een voorbeeld van een url voor een zoekopdracht is Je bladert door de resultaten door de waarde van from telkens met 100 te verhogen totdat deze waarde hoger is dan het totale aantal resultaten. Vervolgens kan je voor elk resultaat details zoals de datum opzoeken via een url waarin de prid is verwerkt, bijvoorbeeld

Voor de manier waarop ik namen van politici heb verzameld en de uiteindelijke resultaten heb geanalyseerd, zie m’n eerdere artikel over lokale media.

De NPO Backstage API is ontwikkeld door de Open State Foundation die zich inzet voor toegankelijke overheidsinformatie. De stichting zat ook achter Politwoops, de site waar verwijderde tweets van politici werden gearchiveerd - totdat Twitter hier een stokje voor stak.