Create ggmap with points, faceted, and each facet zoomed appropriately?
Asked Answered
A

1

9

I want to plot data points for various cities over a greyed-out map from google. As these cities are some distance from each other, I thought I would use a faceted plot.

Creating the map is easy enough; see image and code below. However, each facet shows the same area - in this case Greater London - with the result that the points for other cities are not shown.

Ideally I would like each facet to show each city with the relevant points overlaid. So the facet 'Cardiff' would show a zoomed map of Cardiff and its data points, 'Birmingham' would show Birmingham and its points and so on. I've tried changing various parameters such as zoom and center but I haven't been successful.

How can I show a different city and the relevant points in each facet?

enter image description here

require(ggmap)
require(reshape)

# create fake data
sites <- data.frame(site = 1:6,
                    name = c(
                        "Royal Albert Hall",
                        "Tower of London",
                        "Wales Millenium Centre",
                        "Cardiff Bay Barrage",
                        "Birmingham Bullring",
                        "Birmingham New Street Station"
                        ),
                    coords = c(
                        "51.501076,-0.177265",
                        "51.508075,-0.07605",
                        "51.465211,-3.163208",
                        "51.44609,-3.166652",
                        "52.477644,-1.894158",
                        "52.477487,-1.898836"),
                    subzone = rep(c('London','Cardiff','Birmingham'), each = 2)
                    )

# use function from reshape to split/add column
sites = transform(sites, 
            new = colsplit(coords, split = ",", names = c('lat', 'lon')))
names(sites) <- c(names(sites)[1:4], 'lat','lon')


ggmap(get_googlemap(center = "London", # omitting this doesn't help
                    scale = 2,
                    zoom = 11, # fiddling with zoom doesn't work
                    color = 'bw',
                    maptype = 'roadmap',
                    extent = 'panel',
                    format = "png8",
                    filename = "facet_map_test",
                    )) +
    facet_wrap(~ subzone, ncol = 1) +
    geom_point(data = sites,
               aes(x = lon, y = lat),
               fill = "red",
               size = 3,
               colour = "black",
               shape = 21,
               alpha = 1) +
    theme(legend.position = "none") +
    theme()
Axiomatic answered 5/2, 2014 at 10:58 Comment(1)
Looking at the ggmap() code, I think this is simply not supported: All facets will have to share the same map. Consider creating three separate plots (even with facet_wrap to get the header) and combining them in some way.Randall
T
9

Using the gridExtra package is probably the best way to go. The code:

# getting the maps
londonmap <- get_map(location = c(lon = -0.1266575, lat = 51.504575), zoom = 12)
cardiffmap <- get_map(location = c(lon = -3.16493, lat = 51.45565), zoom = 13)
birminghammap <- get_map(location = c(lon = -1.896497, lat = 52.477565), zoom = 14)

# plotting the maps
p1 <- ggmap(londonmap) +
  geom_point(data = sites[sites$subzone == "London",], 
             aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3), 
             shape = 21) +
  ggtitle("London") +
  theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))

p2 <- ggmap(cardiffmap) +
  geom_point(data = sites[sites$subzone == "Cardiff",], 
             aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3), 
             shape = 21) +
  ggtitle("Cardiff") +
  theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))

p3 <- ggmap(birminghammap) +
  geom_point(data = sites[sites$subzone == "Birmingham",], 
             aes(x = lon, y = lat, fill = "red", alpha = 0.8, size = 3), 
             shape = 21) +
  ggtitle("Birmingham") +
  theme(axis.title = element_blank(), legend.position = "none", plot.margin = unit(c(0,0,0,0), "lines"))

# grouping the plots together in one plot    
grid.arrange(p1, p2, p3, ncol = 1)

The result:

enter image description here

Tailpiece answered 5/2, 2014 at 14:1 Comment(3)
Thanks, +1 for taking the time to do this. I am a longtime user of grid.arrange and already have a solution for the above problem based on it. However, for the purposes of this question I am specifically interested in establishing whether (or not) a faceted solution is possible.Axiomatic
I'm quite sure a faceted solution isn't possible. When using facets, the same background is used for the facetplots. In your case this means that the same map is used as a background (as you showed in the image in your question). Looking at the functions in the ggmap package, I can't discover a function which supports this specific use of facets. There is therefore, in my opinion, only one situation were a faceted solution will work: when you need to plot different groups of points on the same map.Tailpiece
wow! I had never though that grid.arrange could have been used for this! great answer!Petr

© 2022 - 2024 — McMap. All rights reserved.