Scheduled-vs-Actual Accessibility Analysis Steps

Go back to Data and Methods

May 18, 2026

With reference to CfC's baseline conditions of a 'reasonable' morning peak hour journey to the city centre, this is how I first tried to align my own analysis to the CfC report while having several tweaks. The tweaks are necessary because I am no longer just measuring how many people/working adults live within a certain amount of time to the city centre, I am also going to include OD values to measure actual travel demand to the city centre and hopefully do spatial interaction modelling to predict future demand based on hypothetical public transport improvements. This requires administrative geographical units that may not be uniformed across the entire relevant area, so there will be some introduction of median values in the steps. This will go through several iterations and I will update it here on this specific page as the project progresses along.

Ultimately, comparing between scheduled and actual accessibility is just a matter of doing two r5py analysis with different sets of GTFS data -- one with scheduled and the other with retrospective -- now that I have extracted and converted GTFS-RT into retrospective GTFS data. The core steps, which are described, remains the same!

  1. Load the map of relevant city region, broken down into smaller administrative units. As of now, I am choosing the OA level (which is the smallest administrative level)
  2. Load in all bus stops from NaPTAN as points and crop it to the city area, to be initialised as ORIGINS
  3. Separately, do a spatial join of the cropped bus stops with the OAs to establish bus stop-OA relationships
  4. Initialise network using r5py.TransportNetwork to include the city region's road network and GTFS data of choice
  5. Set one place of interest in the city centre as the destination
  6. Run r5py.TravelTimeMatrix with the following parameters:
    • a) Set departure time to 0815 BST, but with a 30-min departure time window (so that arrival times could be between 0845 and 0915 BST as per the CfC report) b) Set transport mode to only bus (will expand to train and trams in the future) c) Set maximum travel time to 1 hour d) Set maximum public transport rides to only one to exclude interchanging of buses or to other modes, as per the baseline conditions in CfC report
  7. Once the function is complete, calculate median travel times from bus stops within each OA to the city centre
  8. Filter for OAs where median travel times are less than or equal to 30 minutes

I did the aforementioned steps for Greater Manchester, with the destination set as Manchester Piccadilly train station. The initial results are HERE!


June 1, 2026

From May 18 until today, I have gathered several important pieces of info.

That means that the quick-and-dirty analysis steps have to be modified! At this point, there are two rough methods that I am interested to explore and discuss with my supervisors!

Method 1: Simply using 2011 Population-Weighted MSOA Centroids to City Centre Bus Stops
  1. Load the population-weighted 2011 MSOA centroids for the relevant city region. This will be the ORIGINS
  2. Load the city centre boundaries
  3. Load the bus stops from NaPTAN and crop it to within the city centre boundaries. This will be the DESTINATIONS
  4. Initialise network using r5py.TransportNetwork to to include the city region's road network and GTFS data of choice
  5. Run r5py.TravelTimeMatrix with the following parameters:
      a) Set departure time to 0815 BST, but with a 30-min departure time window (so that arrival times could be between 0845 and 0915 BST as per the CfC report)
      b) Set transport mode to only bus and walking (will expand to train and trams in the future)
      c) Set maximum travel time to 1 hour and maximum walking time to 10 mins (maximum travel time is increased to 75 mins if measuring for 45-minute journeys)
      d) Set maximum public transport rides to only one to exclude interchanging of buses or to other modes, as per the baseline conditions in CfC report
  6. For each origin with travel time values, get the median travel time to the bus stops in city centre
  7. Filter for population-weighted origins with median travel times less than 30 mins (or 45 mins)
Method 2: Generate Median Travel Times between Bus Stops, then Generate Walking Isochrones, then Overlap with 2011 MSOA
  1. Load the map of relevant city region and its city centre boundaries
  2. Load the bus stops from NaPTAN and crop it to the relevant city region. This will be the ORIGINS
  3. Use the same bus stops data and crop it to within the city centre boundaries. This will be the DESTINATIONS
  4. Initialise network using r5py.TransportNetwork to include the city region's road network and GTFS data of choice
  5. Run r5py.TravelTimeMatrix with the following parameters:
    • a) Set departure time to 0815 BST, but with a 30-min departure time window (so that arrival times could be between 0845 and 0915 BST as per the CfC report)
      b) Set transport mode to only bus (will expand to train and trams in the future)
      c) Set maximum travel time to 1 hour (maximum travel time is increased to 75 mins if measuring for 45-minute journeys)
      d) Set maximum public transport rides to only one to exclude interchanging of buses or to other modes, as per the baseline conditions in CfC report
  6. For each origin bus stop that has travel time values, get the median travel time to the bus stops in city centre
  7. Filter for origin bus stops with median travel times less than 30 mins (or 45 mins)
  8. Use r5py.Isochrones from those remaining bus stops to generate walking isochrones with maximum of 10 minutes
  9. Overlay the walking isochrones map over the map of relevant city region with 2011 MSOA boundaries

As of now, I have NOT run the code yet. I am expecting Method 1 to be computationally faster than Method 2, but Method 1 may also produce a smaller coverage than Method 2. I intend to run the steps using Greater Manchester as the example again, and you can see the results HERE.