Using strava tweets to analyse cycling patterns

A recent report by traffic research institute SWOV analyses accidents reported by cyclists on racing bikes in the Netherlands. Among other things, the data show an early summer dip in accidents: 53 in May, 38 in June and 51 in August. A bit of googling revealed this is a common phenomenon, although the dip appears to occur earlier than elsewhere (cf this analysis of cycling accidents in Montréal).

Below, I discuss a number of possible explanations for the pattern.

Statistical noise

Given the relatively small number of reported crashes in the SWOV study, the pattern could be due to random variation. Also, respondents were asked in 2014 about crashes they had had in 2013, so memory effects may have had an influence on the reported month in which accidents took place. On the other hand, the fact that similar patterns have been found elsewhere suggests it may well be a real phenomenon.


An OECD report says the summer accident dip is specific for countries with «a high level of daily utilitarian cycling» such as Belgium, Denmark and the Netherlands. The report argues the drop is «most likely linked to a lower number of work-cycling trips due to annual holidays».

If you look at the data presented by the OECD, this explanation seems plausible. However, holidays can’t really explain the data reported by SWOV. Summer holidays started between 29 June and 20 July (there’s regional variation), so the dip should have occured in August instead of June.

Further, you’d expect a drop in bicycle commuting during the summer, but surely not in riding racing bikes? I guess the best way to find out would be to analyse Strava data, but unfortunately Strava isn’t as forthcoming with its data as one might wish (in terms of open data, it would rank somewhere between Twitter and Facebook).

A possible way around this is to count tweets of people boasting their Strava achievements. Of course, there are several limitations to this approach (I discuss some in the Method section below). Despite these limitations, I think Strava tweets could serve as a rough indicator of road cycling patterns. An added bonus is that the length of the ride is often included in tweets.

The chart above shows Dutch-language Strava tweets for the period April 2014 - March 2015. Whether you look at the number of rides or the total distance, there’s no early summer drop in cycling. There’s a peak in May, but none in August - September.


According to the respondents of the SWOV study, 96% percent of accidents happened in daylight. Of course this doesn’t rule out that some accidents may have happened in the dusk and there may be a seasonal pattern to this.

Many tweets contain the time at which they were tweeted. This is a somewhat problematic indicator of the time at which trips took place, if only because it’s unclear how much time elapsed between the ride and the moment it was tweeted. But let’s take a look at the data anyway.

I think tweets tend to be posted rather early in the day. Also, the effect of switches between summer and winter time is missing in the median post time (perhaps Twitter converts the times to the current local time).

That said, the data suggests that rides take place closer to sunset during the winter, not during the months of May and August which show a rise in accidents. So, while no firm conclusions should be drawn on the basis of this data, there are no indications that daylight patterns can explain accident patterns.


Perhaps more accidents happen when many people cycle and there’s a lot of rain. In 2013, there was a lot of rain in May; subsequently the amount of rain declined, and there was a peak again in September (pdf). So at first sight, it seems that the weather could explain the accident peak in May, but not the one in August.


None of the explanations for the early summer drop in cycling accidents seem particularly convincing. It’s not so difficult to find possible explanations for the peak in May, but it’s unclear why this is followed by a decline and a second peak in August. This remains a bit of a mystery.


Unfortunately, the Twitter API won’t let you access old tweets, so you have to use the advanced search option (sample url) and then scroll down (or hit CMD and the down arrow) until all tweets have been loaded. This takes some time. I used rit (ride) and strava as search terms; this appears to be a pretty robust way to collect Dutch-language Strava tweets.

It seems that Strava started offering a standard way to tweet rides as of April 2014. Before that date, the number of Strava tweets was much smaller and the wording of the tweets wasn’t uniform. So there’s probably little use in analysing tweets from before April 2014.

I removed tweets containing terms suggesting they are about running (even though I searched for tweets containing the term rit there were still some that were obviously about running) and tweets containing references to mountainbiking. I ended up with 9,950 tweets posted by 2,258 accounts. 1,153 people only tweeted once about a Strava ride. Perhaps the analysis could be improved by removing these.

I had to add 9 hrs to the tweet time, probably because I had been using a VPN when I downloaded the data.

A relevant question is how representative Strava tweets are of the amount of road cycling. According to the SWOV report, about two in three Dutch cyclists on racing bikes almost never use apps like Strava or Runkeeper; the percentage is similar for men and women. The average distance in Strava tweets is 65km; in the SWOV report most respondents report their average ride distance is 60 - 90km.

In any case, not all road cyclists use Strava and not all who use Strava consistently post their rides on Twitter (fortunately, one might add). Perhaps people who tweet their Strava rides are a bit more hardcore and perhaps more impressive rides are more likely to get tweeted.

Edit - the numbers reported above are for tweets containing the time they were posted; this information is missing in about one-third of the tweets.

Here’s the script I used to clean the twitter data.

Moroccan trade union protests and the Arab Spring

In an analysis in the Washington Post, political scientist Matt Buehler argues that the Arab Spring was not just a spontaneous eruption of youth protests: «labour unrest [...] foreshadowed the popular mobilization of youth activists of the Arab blogosphere». In turn, these youth mobilisations created new opportunities for unions.

He illustrates this with an analysis of events in Morocco. Even before the Arab Spring reached the country and culminated in large protests in February 2011, the country had seen trade union protests sparked by the inequality exacerbated by neoliberal reforms. The combination of union and youth protests forced the regime to make concessions, resulting, among other things, in substantial wage and pension increases.

Results from a simple search on Google Trends seem largely consistent with Buehler’s finding that trade union protests preceded the 20 February mobilisation. Searches for trade union names started to rise in 2008 and 2009, that is before the rise in searches for AMDH, a human rights organisation that played a key role in the 20 February protests. Similarly, searches for grève (strike) peaked in 2008 and 2009, whereas searches for manifestation (march / demonstration) and sit in (the latter not shown in the graph) didn’t really start to rise until the end of 2010. It’s also interesting to note that interest in union-related search terms surged again following the February protests.

Exporting Google Trends data

Google Trends has a «download as csv» option which seems handy enough, but it has some issues. For one thing, if you try to export data on multiple search terms, it often seems to omit data for one of the search terms, even if all search terms were correctly shown on screen. I have absolutely no clue what this is about.

A solution might be to download data for each search term separately. A drawback is that data would then be normalised on a per search term basis (i.e., for each term the highest value would be set at 100). This means that it would no longer be possible to compare volume across search terms, but it would still be possible to compare patterns.

However, you then run into the problem that Google will export the data on a per month basis if volume is low and on a per week basis if volume is higher. I don’t understand why Google doesn’t offer the possibility to download all data on a per month basis so you can more easily compare. A hack is suggested here, but I couldn’t get it to work.

Amsterdammers houden van historische grachtenpanden, maar niet van jaren-50 architectuur

O+S, het onderzoeksbureau van de gemeente Amsterdam, heeft een Excelbestand online gezet met een enorme hoeveelheid gegevens over Amsterdamse buurten. Bijvoorbeeld hoe mooi buurtbewoners de huizen in hun buurt vinden. De gemiddelde scores zijn te zien op de kaart hieronder.

Volgens buurtbewoners staan de mooiste huizen in de omgeving van de Leliegracht (gemiddeld een 8,7) in de Westelijke Grachtengordel. De lelijkste huizen zijn te vinden aan de rommelige randen van de stad, bijvoorbeeld rond de Weespertrekvaart in de buurt De Omval.

Het zal niet echt verbazen dat er een tamelijk sterke correlatie is tussen de waarde van woningen (woz) en hoe mooi ze zijn volgens buurtbewoners. Je kan dit op twee manieren uitleggen: ofwel Amsterdammers hebben een patserige smaak, ofwel mensen hebben veel geld over voor mooie woningen, waardoor de waarde van die woningen stijgt (waarschijnlijk een combinatie).

Toevallig was ik net een nieuw bestand van het CBS tegengekomen met gegevens over de bouwperiode van woningen per 4-cijferige postcode. Deze gegevens heb ik gekoppeld aan de gegevens van O+S (voor de haken en ogen zie hieronder, Methode). De scatterplot toont buurten op basis van het percentage woningen uit een bepaalde periode, en de beoordeling van de woningen.

Uit de gegevens kunnen verschillende conclusies worden getrokken:

  • In buurten met een hoog aandeel historische woningen (van voor 1906) vinden bewoners de woningen vaak mooi;
  • Andersom geldt voor buurten met veel naoorlogse woningen (1945 - 1960), zoals de westelijke tuinsteden, dat buurtbewoners lage cijfers geven voor het uiterlijk van de woningen;
  • En architectuur van na 2011 lijkt ook niet zo populair te zijn.

In eerste instantie was ik teleurgesteld in mijn stadsgenoten. Vooral hierom:

  • Ze lijken niet veel waardering te hebben voor de architectuur van de Amsterdamse School, die grotendeels samenvalt met de periode 1906 - 1930 (anders zou er een positieve correlatie zijn geweest tussen de beoordeling en het percentage woningen uit deze periode);
  • Aan de andere kant lijken ze zich niet te realiseren hoe lelijk veel architectuur uit de jaren tachtig is (anders zou je een negatieve correlatie verwachten tussen de beoordeling en het percentage woningen uit de jaren tachtig).

Maar als je wat dieper in de gegevens duikt dan blijkt het nog wel enigszins mee te vallen. Voor sommige buurten zijn gegevens beschikbaar op een meer gedetailleerd niveau dan het niveau dat ik in mijn analyse heb gebruikt.

Voor wat betreft de Amsterdamse school: een tamelijk sensationeel voorbeeld is de Tellegenbuurt in de Diamantbuurt, die een middelmatige 7 krijgt (net boven de mediaan 6,9). Maar uit de meer gedetailleerde gegevens blijkt dat tenminste het westelijke deel van de Tellegenbuurt een iets betere score van 7,4 krijgt. Het zelfde geldt voor het standaardvoorbeeld van de Amsterdamse School, het Schip. Dit ligt in de Spaarndammer- en Zeeheldenbuurt, waar bewoners de huizen een 6,9 geven, maar in de westelijke delen van de Spaarndammerbuurt is dat een 7,5.

Ik blijf erbij dat Amsterdammers de periode 1906 - 1930 onderwaarderen, maar op z’n minst lijken ze wel enige waardering te tonen voor de bekendste hoogtepunten van de Amsterdamse School.

Wat de jaren tachtig betreft: dit was een periode van stadsvernieuwing. Het leverde saaie huizenblokken op in buurten die er verder prima uitzien, zoals de Dapperbuurt, de Oostelijke Eilanden en de oostelijke delen van de Indische Buurt. Deze mix verklaart misschien waarom deze buurten niet altijd extreem lage cijfers krijgen.


De beoordelingen van huizen zijn ontleend aan een enquête uit 2013 waarin bewoners is gevraagd: «Hoe beoordeelt u de woningen in uw buurt? (1=zeer lelijk, 10 =zeer mooi)». Het O+S-bestand met deze beoordelingen is hier te vinden en het CBS-bestand met de bouwperiodes hier.

De grootste uitdaging was om de bestanden aan elkaar te koppelen. Gelukkig bleek dat het CBS ook een bestand heeft met buurtgegevens waarin ook de meestvoorkomende postcode (4 cijfers) is opgenomen (plus een variabele over het percentage woningen dat de betreffende postcode heeft). De link tussen postcode en buurt is imperfect maar niet eens zo heel slecht. Zo geldt voor 57 van de 97 buurten in mijn analyse dat meer dan 90% van de huizen onder de betreffende postcode valt.

Enigszins verassend blijkt dat de spelling van buurtnamen bij O+S in enkele gevallen afwijkt van die van het CBS (waarom ?!). Bijvoorbeeld Bijlmer oost (e,g,k) versus Bijlmer-Oost (E, G, K). Ik heb een aparte tabel gemaakt om de verschillende spellingen aan elkaar te koppelen.

Ik heb R gebruikt om de bestanden aan elkaar te koppelen en om de correlaties te berekenen tussen het aandeel woningen uit een bepaalde periode en de beoordeling van die woningen (code op Github). Het zou niet realistisch zijn om al te sterke correlaties te verwachten: ten eerste zal het aandeel woningen uit een bepaalde periode op z’n best slechts één van de vele factoren zijn die bepalen hoe mooi mensen de woningen in hun buurt vinden, en ten tweede vanwege de noise die is veroorzaakt door de imperfecte koppeling tussen buurt en postcode.

De sterkste correlatie was er voor de periode 1906 - 1930 (.51). Voor 1945 - 1960 was de correlatie -.32 en voor de periode na 2011 -.39. Voor de jaren zestig was er een nog zwakkere, maar op zich wel statistisch significante correlatie van -.22.

Aanvankelijk heb ik een kaart gemaakt met Qgis, maar ik realiseerde me dat enige interactiviteit eigenlijk wel op z’n plaats was. Ik heb een nieuwe versie gemaakt met Leaflet en D3, waarbij ik deze handleiding heb gebruikt om de basics te leren van Leaflet en het combineren van Leaflet met D3. Het aanvankelijke resultaat zag er niet uit, maar met de zwart-witte tiles van Stamen (beter dan OSM black and white) ziet het er al beter uit (waarschijnlijk zal een combinatie van kaart met choropleth er altijd een beetje viezig uitzien).

Amsterdammers like old canal houses and dislike 1950s architecture

The research bureau of the Amsterdam city government (O+S) has published an Excel file containing a wealth of data about Amsterdam’s neighbourhoods. Among other things, it tells us how beautiful Amsterdammers think houses in their neighbourhood are. The average ratings are shown on the map below.

According to locals, the most beautiful houses are to be found around the Leliegracht (rated 8.7 out of 10) in the western canal belt. The ugliest are at the messy margins of the city, for example around the Weespertrekvaart in the Omval neighbourhood.

It will hardly come as a surprise that there’s a pretty strong correlation between the value of houses and how beautiful locals think they are. Either Amsterdammers have a posh taste in houses, or beautiful houses are expensive because people are willing to pay more for them (probably it’s a bit of both).

It so happened I had recently come across a new dataset from Statistics Netherlands (CBS) containing data on the construction period of houses by 4-digit postcode. I linked this data to the O+S data (for the challenges involved see the Method section below). The scatterplot shows neighbourhoods by share of houses from a specified period, and rating.

A few conclusions can be drawn:

  • In neighbourhoods with a high share of historic (pre–1906) houses, locals tend to think houses are beautiful;
  • By contrast, in neighbourhoods with a high share of post-war (1945 - 1960) houses, such as the western garden cities, locals tend to be more critical of the houses in their neighbourhood;
  • And post–2011 architecture doesn’t appear to be very popular either.

My first reaction to these findings was disappointment in my fellow Amsterdammers. Mainly for these reasons:

  • They don’t seem to particularly appreciate the Amsterdam School architecture, which largely coincides with the 1906–1930 period (or there would have been a positive correlation between rating and the share of houses from this period);
  • On the other hand, they don’t seem to realise how ugly much of the 1980s architecture really is (otherwise you’d expect a negative correlation between rating and share of houses from the 1980s).

A deeper dive into the data resulted in a somewhat more nuanced view. For some of the neighbourhoods, data is available at a more detailed level than the level I used in my analysis.

As for the Amsterdam School: a pretty sensational example is the Tellegenbuurt in the neighbourhood Diamantbuurt, which gets a mediocre 7 out of 10 rating (just above the median rating of 6.9). However, the more detailed data shows that at least the western part of the Tellegenbuurt gets a somewhat better 7.4. Similarly, the iconic het Schip housing block is in the Spaarndammer- and Zeeheldenbuurt, where locals rate the houses a 6.9, but the western parts of the Spaarndammerbuurt proper get a rating of 7.5.

I still think Amsterdammers undervalue the 1906–1930 period, but at least they do seem to show some appreciation for some of the most-acclaimed highlights of the period.

As for the 1980s: this was a period of urban renewal. It resulted in dull housing blocks in otherwise decent-looking neighbourhoods such as the Dapperbuurt, the Oostelijke Eilanden and the eastern part of the Indische buurt. This mixture may explain why these neighbourhoods don’t necessarily get very low ratings.


The ratings of houses were collected in 2013, by asking the question «How do you rate the houses in your neighbourhood? (1=very ugly, 10=very beautiful)». The O+S file containing these ratings is available here and the CBS file containing data on period of construction here.

The main challenge consisted in linking the two datasets. Fortunately, the CBS also has a file containing neighbourhood data with the most prevalent 4-digit postcode (and also information on the share of houses that have that postcode). The link between postcode and neighbourhood is imperfect but not too bad. For example, in 57 out of the 97 neighbourhoods in my final analysis, over 90% of the addresses have the postcode associated with the neighbourhood.

Somewhat surprisingly, the O+S spelling of neighbourhoods is in some cases slightly different from the CBS (why?!). For example, Bijlmer oost (e,g,k) versus Bijlmer-Oost (E, G, K). I created a separate table to link the different spellings.

I used R to merge the files and check for correlations between share of houses from a specific period and rating of the houses (code on Github). One shouldn’t expect too strong correlations for two reasons: first, the share of houses from a certain period will be at best just one among many factors that have an influence on rating and second, because of the noise created by the imperfect link between postcode and neighbourhood.

For share of pre–1906 houses there was the strongest correlation with the rating of the houses (.51). For 1945–1960 the correlation was -.32 and for post–2011 it was -.39. There was an even weaker, but still statistically significant, correlation for the 1960s (-.22).

I initially created a map with Qgis, but then I decided the map needed some interactivity. I created a new version with Leaflet and D3, using this tutorial to figure out the basics of Leaflet and how to combine it with D3. The initial result wasn’t pretty, but then I found the black and white tiles by Stamen (better than the OSM black and white) and now I think it looks better (although I guess maps overlaid with a choropleth will always look a bit smudgy).

Nieuwe verhoudingen in de Amsterdamse politiek?

Afgelopen najaar discussieerden Amsterdamse politici op Twitter over de vraag of de verhoudingen tussen coalitie en oppositie veranderd zijn sinds de verkiezing van maart 2014, die resulteerde in een nieuwe coalitie.

Daar valt wel wat over te zeggen aan de hand van het stemgedrag over moties en amendementen gedurende de afgelopen twee jaar. Politiek gezien zijn voorstellen waar zo’n beetje iedereen het mee eens is niet zo interessant:

Een partij kan bijvoorbeeld een hoop moties indienen die heel breed gesteund worden, maar feitelijk weinig veranderen in de opstelling, laat staan het beleid, van de regering. Dit wordt in de literatuur wel «hurrah voting» genoemd: iedereen roept «hoera!», maar is er echt sprake van invloed? (Tom Louwerse)

In zekere zin zou je dat ook kunnnen zeggen over voorstellen die de steun hebben van de volledige coalitie. Interessanter zijn wat ik maar even x-voorstellen noem: voorstellen die niet de steun hebben van alle coalitiepartijen maar die toch worden aangenomen. In de Amsterdamse praktijk gaat het dan vaak om voorstellen waar de VVD tegen was. De verklaring is simpel: coalities zijn in Amsterdam relatief rechts, waardoor linkse coalitiepartijen meer medestanders buiten de coalitie hebben.

Laten we beginnen met de situatie voor de verkiezing van maart 2014. De PvdA was de grootste partij. De coalitie bestond uit GroenLinks, PvdA en VVD, maar de grotere linkse partijen PvdA, GroenLinks en SP hadden een comfortabele meerderheid. De grafiek hieronder laat de indieners van x-voorstellen zien. De pijlen laten zien van wie ze de steun wisten te krijgen om te zorgen dat deze voorstellen werden aangenomen.

De grootte van de cirkels correspondeert met de grootte van de fracties; de roze cirkels zijn coalitiepartijen. De dikte van de pijlen correspondeert met het aantal keer dat een partij een x-voorstel van een andere partij steunde. De richting van de pijlen zie je niet alleen aan de pijlpunt maar ook aan de kromming: pijlen buigen naar rechts.

Het beeld is duidelijk: PvdA en vooral GroenLinks waren de bruggenbouwers die steun wisten te vinden voor x-voorstellen.

En dan de situatie na maart 2014. Inmiddels is D66 de grootste partij en de coalitie bestaat uit SP, D66 en VVD. PvdA en GroenLinks zitten dus in de oppositie, maar ze blijken nog steeds een sleutelrol te spelen bij het aangenomen krijgen van x-voorstellen. Vooral GroenLinks is een bruggenbouwer: deze partij zat achter ongeveer de helft van de x-voorstellen.

De actiefste bruggenbouwer is Jorrit Nuijens (GroenLinks), gevolgd door Maarten Poorter (PvdA) en Femke Roosma (GroenLinks).


Gegevens zijn afkomstig van het raadsarchief van de Amsterdamse gemeenteraad. Daar kunnen uitslagen van stemmingen over moties en amendementen vanaf januari 2013 worden gedownload als Excelbestand. Het bestand (gedownload op 31 januari 2015) bevat informatie over 1.163 (versies van) voorstellen waarover is gestemd tot en met 17 december 2014.

Over dit Excelbestand zijn een aantal opmerkingen te maken. Aan de ene kant is het fantastisch dat deze informatie beschikbaar wordt gesteld. Aan de andere kant is dit bestand een beest dat slechts met flink wat regels code getemd kan worden. De manier waarop stemgedrag wordt vermeld varieert («verworpen met de stemmen van de SP voor», «aangenomen met de stemmen van de raadsleden van drooge en de goede tegen»); de structuur van de titel is in november 2014 aangepast; de Partij voor de Dieren wordt soms aangeduid met de volledige naam en soms met de afkorting; en soms is de tekst die het stemgedrag beschrijft ingekort omdat deze blijkbaar niet in een cel paste. Gezien de complexiteit van het bestand valt niet voor honderd procent uit te sluiten dat er een keer iets mis kan zijn gegaan met het classificeren van de voorstellen.

De analyse richt zich (noodzakelijkerwijs) vooral op zichtbare invloed. De eerste indiener wordt opgevat als initiatiefnemer. In de praktijk zal het vast wel eens voorkomen dat een initiatiefnemer een ander raadslid de eer gunt om eerste indiener te zijn.

De code voor het opschonen en analyseren van de gegevens is hier te vinden. De D3.js code voor de netwerkgrafieken is gebaseerd op dit voorbeeld.