Search code examples
rfor-loopggplot2iterationggmap

Plotting lines over maps in R with ggplot2/ggmap


I'm attempting to create a map in R which overlays an artificial geographic boundary (determined by a set of (x, y) points w/ lat and lon values) over a Google Maps image of an area from ggmap. The code I'm using is below.

ggmap(mapgilbert) +
  geom_point(data = df, aes(x = lon, y = lat, fill = "red", alpha = 0.8), size = 1, shape = 21) +
  guides(fill=FALSE, alpha=FALSE, size=FALSE) +
  for (i in 1:3){
      geom_segment(data = coords, aes(x = lon[[i]], y = lat[[i]], xend = lon[[(i+1)]], yend = lat[[(i+1)]], alpha = 0.8))
  }

Note that coords is a data.frame containing the pertinent lat and lon values, and df is a similar data.frame containing point values; they are both structured properly.

With just one iteration, the above code works fine; the area map appears, the three points I would like to plot appear, and the line drawn between two of them appears as well. However, when I try to perform this action iteratively within a for loop, none of the lines print. I read on a similar post that this is because R's auto-print feature doesn't work within loops, so I tried wrapping the relevant statements in print() functions, but that just returns "NULL" for some reason. I have a feeling I'm making some glaringly obvious mistake but I'm unsure what it is. Thank you in advance!


Solution

  • Since there is no reproducible data, I created a random data. Please provide your data from next time. This is a necessary thing for all SO users when they ask some help.

    What you need is to create a data frame for geom_segment. You do not have to loop through the data at all. Each row of of mydf is a line. You specify two points for longitude and latitude, respectively using x, y, xend and yend.

    library(ggmap)
    library(ggplot2)
    
    # Create a data frame for segments.
    mydf <- data.frame(id = 1:3, 
                       lat_1 = c(37.78, 37.75, 37.73), 
                       lon_1 = c(-122.41, -122.40, -122.405), 
                       lat_2 = c(37.77, 37.75, 37.72), 
                       lon_2 = c(-122.43, -122.42, -122.415))
    
    # Create randam data points.
    set.seed(111)
    
    mydf2 <- data.frame(lon = runif(n = 100, min = -122.49, max = -122.38),
                        lat = runif(n = 100, min = 37.69, max = 37.813))
    
    # Get a map 
    map <- get_map(location = c(left = -122.523, bottom = 37.69,
                                right = -122.35, top = 37.8),
                   maptype = "roadmap", source = "google", color = "bw")
    
    # Plot the points and draw the segments on the map. 
    ggmap(map) + 
    geom_point(data = mydf2, 
               aes(x = lon, y = lat), color = "red", alpha = 0.6, size = 2) + 
    geom_segment(data = mydf, 
                 aes(x = lon_1, y = lat_1, xend = lon_2, yend = lat_2), 
                 color = "green", size = 2, alpha = 0.8, lineend = "round")
    #> Warning: Removed 34 rows containing missing values (geom_point).
    

    Created on 2018-03-25 by the reprex package (v0.2.0).