Ggmap with Geom_Map Superimposed

ggmap with geom_map superimposed

The error message is, I think, the result of an inheritance issue. Typically, it comes about when different data frames are used in subsequent layers.

In ggplot2, every layer inherits default aes mappings set globally in the initial call to ggplot. For instance, ggplot(data = data, aes(x = x, y = y)) sets x and y mappings globally so that all subsequent layers expect to see x and y in whatever data frame has been assigned to them. If x and y are not present, an error message similar to the one you got results. See here for a similar problem and a range of solutions.

In your case, it's not obvious because the first call is to ggmap - you can't see the mappings nor how they are set because ggmap is all nicely wrapped up. Nevertheless, ggmap calls ggplot somewhere, and so default aesthetic mappings must have been set somewhere in the initial call to ggmap. It follows then that ggmap followed by geom_map without taking account of inheritance issues results in the error.

So, Kohske's advice in the earlier post applies - "you need to nullify the lon aes in geom_map when you use a different dataset". Without knowing too much about what has been set or how they've been set, it's probably simplest to globber the lot by adding inherit.aes = FALSE to the second layer - the call to geom_map.

Note that you don't get the error message with ggplot() + myMap + Limits because no aesthetics have been set in the ggplot call.

In what follows, I'm using R version 2.15.0, ggplot2 version 0.9.1, and ggmap version 2.1. I use your code almost exactly, except for the addition of inherit.aes = FALSE in the call to geom_map. That one small change allows ggmap and geom_map to be superimposed:

library(sp)
library(spdep)
library(ggplot2)
library(ggmap)
library(rgdal)

#Get and fiddle with data:
nc.sids <- readShapePoly(system.file("etc/shapes/sids.shp", package="spdep")[1],ID="FIPSNO", proj4string=CRS("+proj=longlat +ellps=clrk66"))
nc.sids=spTransform(nc.sids,CRS("+init=epsg:4326"))

#Get background map from stamen.com, plot, looks nice:
ncmap = get_map(location=as.vector(bbox(nc.sids)),source="stamen",maptype="toner",zoom=7)
ggmap(ncmap)

#Create a data frame with long,lat,Z, and plot over the map and a blank plot:
ncP = data.frame(coordinates(nc.sids),runif(nrow(nc.sids)))
colnames(ncP)=c("long","lat","Z")

ggmap(ncmap)+geom_point(aes(x=long,y=lat,col=Z),data=ncP)
ggplot()+geom_point(aes(x=long,y=lat,col=Z),data=ncP)

#give it some unique ids called 'id' and fortify (with vitamins and iron?)
nc.sids@data[,1]=1:nrow(nc.sids)
names(nc.sids)[1]="id"
ncFort = fortify(nc.sids)

#Now, my map and my limits, I want to plot the 74 birth rate:
myMap = geom_map(inherit.aes = FALSE, aes(fill=BIR74,map_id=id), map=ncFort,data=nc.sids@data)
Limits = expand_limits(x=ncFort$long,y=ncFort$lat)

# and on a blank plot I can:
ggplot() + myMap + Limits

# but on a ggmap I cant:
ggmap(ncmap) + myMap + Limits

The result from the last line of code is:

Sample Image

Using ggplot's ggmap function to superimpose two maps on top of each other

The original problem is exactly solved using the ggmap version 2.0 inset_ggmap():

require(ggmap)

map.background <- get_map(c(lon = -122, lat = 47.5), map = "toner-background")
map.lines <- get_map(c(lon = -122, lat = 47.5), map = "toner-lines")
map.labels <- get_map(c(lon = -122, lat = 47.5), map = "toner-labels")

set.seed(127)
df <- data.frame(lon = rnorm(25, mean = -122.2, sd = 0.2),
lat = rnorm(25, mean = 47.5, sd = 0.1),
size = rnorm(25, mean = 15, sd = 5))

ggmap(map.background) +
geom_point(data = df,
aes(x = lon, y = lat, size = size),
color = "blue", alpha = 0.8) +
scale_size_identity(guide = "none") +
inset_ggmap(map.lines) +
inset_ggmap(map.labels)

Sample Image

R overlay geom_polygon with ggmap object, spatial file conversion

The coordinate system used by your shapefile isn't lat-lon. You should transform it before converting it into a dataframe for ggplot. The following works:

shpfile <- spTransform(shpfile, "+init=epsg:4326") # transform coordinates
tidydta2 <- tidy(shpfile, group=group)

wisc <- get_map(location = c(lon= -89.75, lat=44.75), zoom=7)

ggmap(wisc) +
geom_polygon(aes(x=long, y=lat, group=group),
data=tidydta2,
color="dark red", alpha=.2, size=.2)

plot

For future reference, do check your coordinate values by printing the dataframe to console / plotting with visible x/y axis labels. If the numbers are wildly different from that of your background map's bounding box (e.g. 7e+05 vs. 47), you probably need to make some transformations. E.g.:

> head(tidydta) # coordinate values of dataframe created from original shapefile
# A tibble: 6 x 7
long lat order hole piece group id
<dbl> <dbl> <int> <lgl> <chr> <chr> <chr>
1 699813. 246227. 1 FALSE 1 0.1 0
2 699794. 246082. 2 FALSE 1 0.1 0
3 699790. 246007. 3 FALSE 1 0.1 0
4 699776. 246001. 4 FALSE 1 0.1 0
5 699764. 245943. 5 FALSE 1 0.1 0
6 699760. 245939. 6 FALSE 1 0.1 0

> head(tidydta2) # coordinate values of dataframe created from transformed shapefile
# A tibble: 6 x 7
long lat order hole piece group id
<dbl> <dbl> <int> <lgl> <chr> <chr> <chr>
1 -87.8 42.7 1 FALSE 1 0.1 0
2 -87.8 42.7 2 FALSE 1 0.1 0
3 -87.8 42.7 3 FALSE 1 0.1 0
4 -87.8 42.7 4 FALSE 1 0.1 0
5 -87.8 42.7 5 FALSE 1 0.1 0
6 -87.8 42.7 6 FALSE 1 0.1 0

> attr(wisc, "bb") # bounding box of background map
# A tibble: 1 x 4
ll.lat ll.lon ur.lat ur.lon
<dbl> <dbl> <dbl> <dbl>
1 42.2 -93.3 47.2 -86.2

# look at the axis values; don't use theme_void until you've checked them
cowplot::plot_grid(
ggplot() +
geom_polygon(aes(x=long, y=lat, group=group),
data=tidydta,
color="dark red", alpha=.2, size=.2),
ggplot() +
geom_polygon(aes(x=long, y=lat, group=group),
data=tidydta2,
color="dark red", alpha=.2, size=.2),
labels = c("Original", "Transformed")
)

comparison

Overlaying ggplot, geom_polygon choropleth on ggmap giving errors

I looked into your case and ended up doing the work in my way. I hope you do not mind that. What you needed was to have a data set with amount in the fake data set in your polygon data. I guess that is why you were probably using left_join. Anyway, each polygon had different numbers of data points. I calculated the total of data points for each polygon and created num. Using this, you can create a vector with DAUID and replace id in mymap2. Once you arrange your data, you get a raster map with ggmap. Then, you draw polygons on top of the raster map. You ca control alpha value and see how colors come out. If you lower the value to 0.1, for instance, it is hard to see difference among colors. You may want to consider another way to show roads. One way would be to use Canadian road data set and draw some major roads in Edmonton. Hope this will help you.

library(readr)
library(dplyr)
library(ggplot2)
library(ggmap)
library(rgdal)

#load data
mydata <- read_csv("fakedata.csv") %>%
rename(id = DAUID)

#Load in the shape file
mymap <- readOGR(dsn = ".", layer = "gda_048b06a_e")

mymap@data$DAUID <- as.numeric(as.character(mymap@data$DAUID))

mymap2 <- fortify(mymap)

# Get the number of data points for each polygon
group_by(mymap2, as.numeric(id)) %>%
summarize(total = n()) -> num

# Replace id with DAUID, and merge with mydata
mymap2 %>%
mutate(id = rep(unique(mymap$DAUID), num$total)) %>%
left_join(mydata, by = "id") -> mymap2

#map of Edm
edmonton <- get_map(location = "edmonton",maptype = "road")

ggmap(edmonton) +
geom_map(data = mymap2, map = mymap2,
aes(x = long, y = lat, group = group, map_id = id, fill = amount),
color = "black", size = 0.2, alpha = 0.3) +
scale_fill_gradient(low = "white", high = "red") +
coord_map(xlim = c(-113.35, -113.68), ylim = c(53.44, 53.65))

Sample Image

Plotting shape files with ggmap: clipping when shape file is larger than ggmap

Here is my attempt. I often use GADM shapefiles, which you can directly import using the raster package. I subsetted the shape file for NY, NJ and CT. You may not have to do this in the end, but it is probably better to reduce the amount of data. When I drew the map, ggplot automatically removed data points which stay outside of the bbox of the ggmap image. Therefore, I did not have to do any additional work. I am not sure which shapefile you used. But, GADM's data seem to work well with ggmap images. Hope this helps you.

library(raster)
library(rgdal)
library(rgeos)
library(ggplot2)

### Get data (shapefile)
us <- getData("GADM", country = "US", level = 1)

### Select NY and NJ
states <- subset(us, NAME_1 %in% c("New York", "New Jersey", "Connecticut"))

### SPDF to DF
map <- fortify(states)

## Get a map
mymap <- get_map("new york city", zoom = 10, source = "stamen")

ggmap(mymap) +
geom_map(data = map, map = map, aes(x = long, y = lat, map_id = id, group = group))

Sample Image

If you just want lines, the following would be what you are after.

ggmap(mymap) +
geom_path(data = map, aes(x = long, y = lat, group = group))

Sample Image

Getting a map with points, using ggmap and ggplot2

Your longitude and latitude values in geom_point() are in wrong order. lon should be as x values and lat as y values.

 p + geom_point(data=d, aes(x=lon, y=lat),size=5)

Overlay multiple data with 2D density using different colours onto ggmap

The primary problem seems to be solved by using the correct columns for x and y aesthetics:

p = map2 + 
stat_density2d(aes(x=X2 ,y=X1, z=X3, color=group, alpha=..level..),
data=d, size=2, contour=TRUE)

ggsave("map.png", plot=p, height=7, width=7)

Sample Image

Plotting to shapefile region with ggplot / ggmap

ggplot(data=England.fort, aes(x=long, y=lat, group=group, Fill=Total)) + 
geom_polygon() +
theme_bw()

Does the trick. Thanks



Related Topics



Leave a reply



Submit