Visualising Amsterdam’s cyclists

Bike City Amsterdam, a new book by Fred Feddes and Marjolein de Lange, recounts how Amsterdam developed a cycling policy (more on the book below). An important source for the book is the archive of the Amsterdam branch of cyclists’ organisation Fietsersbond. In addition, traffic data was used to analyse trends.

An interesting dataset consists of counts of the number of cyclists, cars and other road users moving into and out of Amsterdam’s city centre, over the years 1980–2009. Most of the locations where traffic was counted are on the Singelgracht, which encircles Amsterdam’s city centre.

The data represents manual counts on a single day, between 7am and 7pm, of traffic in both directions.

I was asked to think about a way to visualise this dataset, which posed an interesting challenge (and was a lot of fun to do). Below, I’ll discuss a few of the options we considered.

Radar chart

Given the geographical distribution of counting locations, it seemed to make sense to try a circular chart design. In fact, that idea had also occurred to the city’s infrastructure department. In a 2007 fact sheet, they used a radar chart (or cobweb chart) to visualise the Singelgracht bicycle counts.

Incidentally, they didn’t use the term radar chart, but called it a fan (waaier). They used a bicycle metaphor to describe how it works: «from the middle, the counting locations around the city centre are connected like spokes in a bicycle wheel».

The chart looks really nice, but this chart type also has a drawback: there’s an implicit suggestion that the area within the purple line represents the number of crossings, which is in fact misleading (see this article for a discussion of a similar problem). Another limitation is that the chart doesn’t show how bicycle traffic changed - although it would be possible to make a version with separate lines representing 1980 and 2009.

Radial lollipop chart

As an alternative, I created what I’ll call a radial lollipop chart (to my knowledge, this chart type didn’t exist yet). The chart library that I use, D3.js, doesn’t seem to have a method to draw the ‘spokes’, or at least I couldn’t find it. Therefore, I wrote a function that calculates the start and end points of the lines. I had long forgotten how to use sine and cosine, so I had to look that up. I’ve published the code here.

Here’s a radial lollipop chart showing how cycling has increased at virtually all the Singelgracht crossings.

And here’s one showing the opposite effect for cars:

I love it when a chart has data points that break out of the chart area - although this is perhaps a bit extreme. The outliers are due to the fact that a large share of car traffic uses the Wibautstraat - IJtunnel route. I could have changed the scale to include those outliers, but then changes on other routes as well as changes in bicycle use would have become much more difficult to discern.

Area chart

I rather like the radial lollipop chart, but it has a limitation: it shows changes between 1980 and 2009, but not when those changes happened. Car use started to go down before cycling really started to increase, but from the radial lollipop chart you couldn’t tell.

This is why the chart used in the book is an area chart, with colours corresponding to the broad geographical orientation of the crossings. Simple, but effective. And if you want to explore the details, click here for a draft version of the charts: bicycle, car.

About the book and exhibition

On 4 April, the Amsterdam branch of cyclists’ organisation Fietsersbond has handed over its archive to the Municipal Archive. Marjolein de Lange, who coordinated a volunteer project to prepare the archive, came up with the idea to use the material as input for a book - a project she carried out with author Fred Feddes.

This resulted in a very interesting book about activism versus cooperation; the place of cycling in urban planning; and how the magic power of Amsterdam’s cycling culture decided the epic fight for the right to cycle through the passage under the Rijksmuseum. The book, which contains a wealth of great photos; maps and posters, is a must-read for anyone interested in cycling, Amsterdam, or activist poster design. It’s been published both in Dutch and in English. There’s also an exhibition at the Municipal Archive (until 30 June, Vijzelstraat 32, access is free).

Using a jagged baseline to indicate a broken y-axis

In an article for the recently created Data Visualisation Society, R.J. Andrews suggests using a jagged baseline to indicate a broken y-axis (i.e., an axis that doesn’t start at zero). The idea - inspired by some beautiful charts dating back to WWI - is to suggest that the bottom part of the chart has been torn off. I like the idea - but I found it isn’t easy to implement.

Contrary to the view of some chart fundamentalists, using a y-axis that doesn’t start at zero can be perfectly ok in some situations. Still, one might want to alert the reader that the zero line is missing. One way is to add a little zigzag or some other symbol to the y-axis, as shown here. And then there’s Andrews’ suggestion to use a jagged baseline.

I tried to implement this in a chart that shows the number of flights at Schiphol Airport. For background: Schiphol has all but reached the cap of 500,000 flights per year, agreed on after negotiations between local residents and the aviation industry. There’s currently a heated debate on whether Schiphol should be allowed to grow further. Experts expect that maintaining the cap will result in more efficient use of the available slots (e.g. fewer short-distance flights, fewer low-cost flights, larger aircraft and fewer empty seats).

Creating a jagged baseline is a bit of a hassle: you have to remove the regular baseline, move the axis labels down a bit and create a new, jagged baseline.

And then there are some design issues. Having the baseline and the ‘regular’ chart lines look too similar may cause confusion. In fact, all of Andrews’ examples have very pronounced chart lines, which are clearly distinct from the baseline. If you prefer a more subtle approach, another solution is to use a light colour for the baseline.

Then again, it also matters whether there are gridlines. After some experimenting, I think the jagged baseline only works well with gridlines added; without them it looks a little weird. But see for yourself if you agree.

I’ve written a Python script to download and clean Schiphol Airport traffic data; find it on Github.


How to investigate assets: lessons from The Wire

I’m rewatching The Wire. It’s a great series anyhow, but for researchers, episode 9 of the first season (2002) is especially interesting. It features detective Lester Freamon instructing detectives Roland Pryzbylewski and Leander Sydnor how to investigate the assets of drug kingpin Avon Barksdale.

They use microfilm instead of the Internet. They don’t have databases like Orbis, Companyinfo or OpenCorporates, and they don’t seem to calculate social network metrics. Yet the general principles behind Freamon’s methodology still make perfect sense today:

Start with the nightclub that Barksdale owns. Look up Orlando’s, by address, you match it, and you see it’s owned by - who?

Turns out it’s owned by D & B Enterprises. Freamon tells Prez to take that information to the state office buildings on Preston Street.

Preston Street?

Corporate charter office.

Corporate who?

They have the paperwork on every corporation and LLC licensed to do business in the state. You look up D & B Enterprises on the computer. You’re going to get a little reel of microfilm. Pull the corporate charter papers that way. Write down every name you see. Corporate officers, shareholders or, more importantly, the resident agent on the filing who is usually a lawyer. While they use front names as corporate officers, they usually use the same lawyer to do the charter filing. Find that agent’s name, run it through the computer, find out what other corporations he’s done the filing for, and that way we find other front companies.

This is pretty much the same approach you’d take when investigating shady temp agencies: trace connections via (former) shareholders, board members, company addresses and related party transactions. And, of course, try to figure out where the profits go.

On that aspect, Freamon also has some wisdom to share:

And here’s the rub. You follow drugs, you get drug addicts and drug dealers. But you start to follow the money, and you don’t know where the fuck it’s gonna take you.


My first Python package

As a self-taught programmer, I sometimes feel a bit uneasy about the code I write. Sure, it may work, but there’s probably a more efficient and more elegant way to do it. These doubts notwithstanding, I’ve just published my first Python package: limepy.

Its purpose is simple: it helps you process and summarise LimeSurvey data. LimeSurvey is a survey tool, somewhat similar to Surveymonkey. It’s different in that it’s open source, and probably more versatile.

If you download survey data as a csv, the answers to question types such as multiple choice questions or blocks of questions (‘arrays’) will be spread out over multiple columns. One task of limepy is to make sure all the data for a specific item end up in one table.

Limepy will also help you with a number of other tasks, like downloading survey data, creating a codebook, printing answers to open-ended questions and printing the answers of an individual respondent.

Find the package on Github and PyPI. Install with pip install limepy. Feedback welcome.

Delete Facebook

This is becoming a bit of a tradition: me writing about people who make a New Year’s resolution to quit Facebook. The story is simple: around the turn of the year, there’s a peak in people googling how to quit smoking, but there’s an even larger peak in people trying to figure out how to delete their Facebook account.

But this year, the story is a bit more complicated (and more interesting).

Google Trends data isn’t available yet for the last days of the year, so there’s no new peak in searches for “quit smoking” yet. Other than that, the yearly pattern is dwarfed by a huge peak in search volume for “delete Facebook” in the week starting on 18 March. What happened?

The Guardian has helpfully created an overview of Facebook-related incidents during 2018; I’ve added a few stories that also seemed relevant (for sources, see Method below; thanks to Vicki Boykis for the suggestion to annotate the Google Trends chart).

No surprise: the largest peak in “delete Facebook” searches happened a few days after the publication of the Cambridge Analytica story on 17 March. The news resulted in a veritable #deletefacebook campaign, although according to Mark Zuckerberg, «I don’t think we’ve seen a meaningful number of people act on that.»

Arwa Mahdawi has argued that deleting your Facebook account isn’t a bad New Year’s resolution, even though it probably won’t change how the company operates: «Facebook’s abuse of power isn’t a problem that we can solve as individuals. Technology giants must be regulated.»

So how much impact did the controversy have on Facebook? One way to try and answer this is to look at the share price.

The pattern for Facebook is rather interesting. The share price dropped after the publication of the Cambridge Analytica story, but quickly picked up again. But then it took a plunge on 25 July, resulting in ‘the biggest-ever one-day wipeout in U.S. stockmarket history’.

One possible interpretation is that investors initially thought the Cambridge Analytica story wasn’t going to harm Facebook’s profits. But when Facebook published its Q2 earnings report, they were shocked to learn that user growth had stalled.

But the chart also shows that all major tech companies saw their share prices go down. This suggests there’s more going on than users leaving Facebook. In addition to broader economic trends, a likely explanation is that investors fear more government regulation of major tech companies in response to the controversies they are involved in (and also to their dominant market position). While this may not be the whole story, it does seem to support Mahdawi’s view about the key role of regulation.


Note that Google Trends data should be interpreted with caution because Google doesn’t provide much detail on the methodology used to produce the data.

For periods longer than three months, only weekly data can be downloaded. For the 2018 chart I wanted daily data. As suggested here, I downloaded three-month batches with overlapping data and then used the overlapping dates to calculate a ratio to adjust the scales. Here’s the code:

import pandas as pd
import numpy as np
def stitch(df1, df2):
    df1.index =
    df2.index =
    overlapping = [d for d in if d in list(]
    ratios = [df1.loc[d, 'delete facebook'] /
              df2.loc[d, 'delete facebook']
              for d in overlapping]
    ratio = np.median(ratios)
    for var in ['delete facebook', 'quit smoking']:
        df2[var] *= ratio
    df = pd.concat([df1, df2[]])
    return df
df = dfs[0]
for df2 in dfs[1:]:
    df = stitch(df, df2)

I used this Guardian article as my main source on Facebook-related incidents in 2018. I added a few from other sources: in April, Facebook announced 87 million people had been affected by the Cambridge Analytica scandal. Subsequently, it announced that it would notify people who had been affected. Dutch comedian Arjen Lubach organised a Bye Bye Facebook event (reminiscent of the 2015 Facebook Farewell Party). In September, Pew found that one in four Americans had deleted the Facebook app from their phone; and later that month a Chinese hacker threatened to delete Mark Zuckerberg’s Facebook account.