How to create interactive plots of GTFS data in R using Leaflet?


Rafa Pereira

I want to create an interactive map that shows the public transport lines in a city. I'm trying to use Leaflet in R to do this (but I'm open to alternatives, suggestions?)

Data: The data for the transfer system is in GTFS format, organized as text files (.txt), which I read into R as a data frame. *

Problem: I can't find how to indicate the ID (variable shape_id) of each Poly line, so the plot will actually follow the route of each transit line. Instead, it connects the dots in random order.

Here's what I've tried so far without success:

# Download GTFS data of the Victoria Regional Transit System
  tf <- tempfile() 
  td <- tempdir()
  ftp.path <- "http://www.gtfs-data-exchange.com/agency/bc-transit-victoria-regional-transit-system/latest.zip"
  download.file(ftp.path, tf) 

# Read text file to a data frame
  zipfile <- unzip( tf , exdir = td )
  shape <- read.csv(zipfile[9])

# Create base map
  basemap <- leaflet() %>% addTiles()


# Add transit layer
  basemap  %>% addPolylines(lng=shape$shape_pt_lon, lat=shape$shape_pt_lat, 
                            fill = FALSE,
                            layerId =shape$shape_id) 

I am glad to receive your comment on this.

*I know it is possible to import this data into GIS software such as QGIS to create a shapefile and then use readOGR to read the shapefile into R. Robin Lovelace shows how to do it . However, I am looking for a pure R solution. ;)

ps. Kyle Walker has an excellent introduction to interactive maps in R using Leaflet . Unfortunately, he doesn't cover polylines in this tutorial.

Robin Lovelace

Your problem is not the method but one of the data: note that you downloaded 8 MB and the line file you are trying to load into Leaflet via Shiny is 5 MB. As a general principle, new methods with tiny datasets should always be tried first before scaling up. Here's what I did below to diagnose the problem and fix it.

Stage 1: Explore the data and subset it

pkgs <- c("leaflet", "shiny" # packages we'll use
  , "maps" # to test antiquated 'maps' data type
  , "maptools" # to convert 'maps' data type to Spatial* data
  )
lapply(pkgs, "library", character.only = TRUE)


class(shape)
## [1] "data.frame"

head(shape)

##   shape_id shape_pt_lon shape_pt_lat shape_pt_sequence
## 1 1-39-220    -123.4194     48.49065                 0
## 2 1-39-220    -123.4195     48.49083                 1
## 3 1-39-220    -123.4195     48.49088                 2
## 4 1-39-220    -123.4196     48.49123                 3
## 5 1-39-220    -123.4197     48.49160                 4
## 6 1-39-220    -123.4196     48.49209                 5

object.size(shape) / 1000000 # 5 MB!!!

## 5.538232 bytes

summary(shape$shape_id)
shape$shape_id <- as.character(shape$shape_id)
ids <- unique(shape$shape_id)
shape_orig <- shape
shape <- shape[shape$shape_id == ids[1],] # subset the data

Stage 2: Convert to Spatial* object

Is this like an object data.frameon a map ?

state.map <- map("state", plot = FALSE, fill = TRUE)
str(state.map)

## List of 4
##  $ x    : num [1:15599] -87.5 -87.5 -87.5 -87.5 -87.6 ...
##  $ y    : num [1:15599] 30.4 30.4 30.4 30.3 30.3 ...
##  $ range: num [1:4] -124.7 -67 25.1 49.4
##  $ names: chr [1:63] "alabama" "arizona" "arkansas" "california" ...
##  - attr(*, "class")= chr "map"

Yes , it's similar, so we can map2Spatial*convert it using:

shape_map <- list(x = shape$shape_pt_lon, y = shape$shape_pt_lat)
shape_lines <- map2SpatialLines(shape_map, IDs = ids[1])
plot(shape_lines) # success - this plots a single line!

String

Stage 3: Join all the rows together

A forloop will do this nicely. Note that we only use the first 10 rows. All lines used :2:length(ids)

for(i in 2:10){
  shape <- shape_orig[shape_orig$shape_id == ids[i],]
  shape_map <- list(x = shape$shape_pt_lon, y = shape$shape_pt_lat)
  shape_temp <- map2SpatialLines(shape_map, IDs = ids[i])
  shape_lines <- spRbind(shape_lines, shape_temp)
}

Stage 4: Plot

Using SpatialLinesobjects makes the code a bit shorter - in this case, this will draw the first 10 lines:

leaflet() %>% 
  addTiles() %>%
  addPolylines(data = shape_lines)

top 10

in conclusion

You need to process and manipulate the data before converting it to a Spatial* data type with the correct ID for plotting. maptools::map2Spatial*, unique()while a clever forloop can do the trick.

Related


How to create interactive plots of GTFS data in R using Leaflet?

Rafa Pereira I want to create an interactive map that shows the public transport lines in a city. I'm trying to use Leaflet in R to do this (but I'm open to alternatives, suggestions?) Data: The data for the transfer system is in GTFS format, organized as text

How to create interactive plots of GTFS data in R using Leaflet?

Rafa Pereira I want to create an interactive map that shows the public transport lines in a city. I'm trying to use Leaflet in R to do this (but I'm open to alternatives, suggestions?) Data: The data for the transfer system is in GTFS format, organized as text

How to create interactive plots of GTFS data in R using Leaflet?

Rafa Pereira I want to create an interactive map that shows the public transport lines in a city. I'm trying to use Leaflet in R to do this (but I'm open to alternatives, suggestions?) Data: The data for the transfer system is in GTFS format, organized as text

How to create interactive plots of GTFS data in R using Leaflet?

Rafa Pereira I want to create an interactive map that shows the public transport lines in a city. I'm trying to use Leaflet in R to do this (but I'm open to alternatives, suggestions?) Data: The data for the transfer system is in GTFS format, organized as text

Create interactive plots in R

GCGM I'm wondering if it's possible in R (RStudio) to have an interactive plot where the user clicks on an image and uses it as input to be processed. Here is my situation: I have a raster that I draw plot(NDVI[[4]]) [![Enter image description here][1]][1] Af

Create interactive plots in R

GCGM I'm wondering if it's possible in R (RStudio) to have an interactive plot where the user clicks on an image and uses it as input to be processed. Here is my situation: I have a raster that I draw plot(NDVI[[4]]) [![Enter image description here][1]][1] Af

Interactive maps in R using leaflet/gloss

Yasushi I want to create a map with a sidebar where you can select a range of time periods. The idea is that the map only shows markers for hotels that were open during that period. I didn't know how to do this, so I tried to use selectInput as it seemed easie

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

How to prevent recursion using interactive plots in bqplot?

John Mahoney I created an interactive scatterplot with a place (using ) that bqplotallows you to drag points in it .enable_move=True I don't want the user to drag the point above the line y=x. If they do, I'd like this point to go back to the nearest point. Th

Create Layer Plots Using Base R Plots

adam.888 I'm trying to make a layer map in base R with three layers: the area below the y1 line is shaded cyan, the area between the y1 and y2 lines is shaded yellow, and the area between y2 and y3 is shaded gray. I tried: x <- 1:100 y1 <- 2*x+3 y2 <- y1 +4*x+

Generate data to create plots in R

FKG I started with the task of replicating the graphs I saw in my research. However, when trying this method, I am confused about how it is created. This is what the plot looks like: The "x" in the graph represents the percentage of countries with a specific s

Interactive plots in R

Statistics 555 Using the plotly library, I have plotted the following in R: library(dplyr) library(ggplot2) library(plotly) set.seed(123) df <- data.frame(var1 = rnorm(1000,10,10), var2 = rnorm(1000,5,5)) df <- df %>% mutate(var3 = ifelse(