Pittsburgh Bus Wait Times

February 2016

Routes 61A, 61B, 61C, 61D

Bus travel times for public transit users is the sum of waiting time and transit time. Whereas trip time is generally predictable, wait times can vary considerably based on bus travel speed patterns. Pittsburgh's buses, like many mass transit systems, are prone to bunching, which can cause wait times to vary considerably. In this byte, I explore visualizing how expected wait times vary throughout the course of a day.


The Port Authority of Allegheny County utilizes an automatic vehicle location (AVL) service to provide real-time location information for its buses. Expanding on previous work, I collected location data for all Route 61 buses for the month of February 2016.

The dataset was created and prepared in the following manner:

  1. The location of all Route 61 buses was collected and warehoused in a SQL database once every 60 seconds for the month of Feb 2016.
  2. Bus location information was exported to a flat file and imported to R for processing. (In an ideal world, I would have done the data processing in Python, and in a manner that allows new data to be easily and automatically incorporated. In reality, however, my data munging and processing skills are much stronger in R than Python, so I used the tool with which I was most familiar.)
  3. The dataset records the location of each bus, as well as the name of the last stop that the bus passed. In many cases, a bus would reported several successive locations without having passed an named spot. In these instances, only the first record past a given stop was retained.
  4. I used plyr to subset the dataset according to stop and hour of day, and to calculate the mean for each.
  5. The resulting dataset of mean wait times by hour for each stop was exported to a flat file.
Choose a bus stop below to see the average times between bus arrivals, average wait time, and the excess waiting time (average wait time minus scheduled wait time).

1. Select Stop Using Map

2. Average Time Between Bus Arrivals at Stop

Stop Name:

3. Average and Excess Wait Times at Stop


This byte allows the user to explore the average wait times for different stops. The first graph is created using a Google API, and was simple and straightforward to implement.

The second graph is created using D3. For someone experienced with creating visualizations with D3, I imagine this would also be straightforward. I wanted to contrast average waiting times with the excess waiting time, so I graphed the excess waiting time below the average waiting time. Unfortunately, I struggled to get the scale to line up correctly. In reality, it seems I may need to manually code a scale, rather than using D3's excellent yAxis and scale functions.

The visual is a bit cumbersome to navigate. Unless viewed on a large screen, the user must scroll down after selecting a stop to see the data, which makes it hard to compare between stops. A more effective implementation might place the navigation map on the left-hand side, and graphs on the right-hand side.


My conclusion is that D3 is incredible, but non-trivial to implement. I leave the following for myself to improve this byte:

  1. Fix D3 chart so that the left-hand scale displays correctly, and add appropriate labels to the axes.
  2. Add a toggle to switch the map markers between inbound routes and outbound routes.
  3. Change the layout such that the map and graphs sit side-by-side.