I was wondering if anyone knows how to keep the google copyright information on maps plotted (with a new scale) by ggmap in R?
For example:
library(ggmap)
library(ggplot2)
# download basemap
ggmap::register_google(key="xxx") # insert your hey here xxx
ggmap::ggmap_show_api_key()
base_map <- get_googlemap(center = c(lon= -2.325278, lat=54.6000000), zoom = 5, style = 'element:labels|visibility:off',color= "bw")
When I plot base_map
without changing the scale the copyright information is inserted at the bottom of the plot as so:
ggmap(base_map, extent = "panel")
However, when I plot base_map
with a new x
and y axis
to zoom into mainland Britain. I also crop off the copyright info. As below:
ggmap(base_map, extent = "panel")+
scale_x_continuous(limits = c(-7, 3), expand = c(0, 0)) +
scale_y_continuous(limits = c(49.5, 59), expand = c(0, 0))
Does anyone know how I can get the second plot but with the copyright information that I need for publication?
I have tried to change the zoom=
argument in the get_googlemap()
function but it always seems to either cut the top or bottom off the UK and I need to be able to see the whole area for when I plot my data.
Thank you so much for your help in advance!
Although seemingly simple, this is actually a quite complex issue. I did some research and found out that you can achieve this by tweaking both size
and scale
arguments. However, if you are using ggmap
v3.0.0 as I do, you will find that specifying non-square dimensions just gives you a "noisy image" as follows:
base_map <- ggmap::get_googlemap(center = c(lon= -2.325278, lat=54.6000000), zoom = 5, size = c(331, 367), style = 'element:labels|visibility:off', color= "bw")
ggmap(base_map, extent = "panel")
This involves a known bug in the ggmap
package. It has not yet been resolved. Although there exists a solution as mentioned here, that only partially solves the problem because the solution has failed for some cases mentioned in this post. Hence, I'd suggest rewriting that function to make it work in a robust way. Luckily, after investigating the source code, I found the problem not so hard to deal with. The problem results from some image-processing failure in the get_goolemap
function. Therefore, outsourcing the image processing in that function to a dedicated package is a simple workaround.
Consider this get_googlemap2
(to make it simple, I have ignored all those argument checkings in the original get_goolemap
, so be careful with your inputs)
require(RgoogleMaps)
require(httr)
require(magick)
require(urltools)
require(tibble)
get_googlemap2 <- function(
api_key = "Your API Key",
center = c(lon = -95.3632715, lat = 29.7632836),
zoom = 10, size = c(640, 640), scale = 2,
maptype = c("terrain", "satellite", "roadmap", "hybrid"),
grayscale = FALSE, style
) {
maptype <- match.arg(maptype)
params <- c(
center = paste0(center[c(2L, 1L)], collapse = ","),
zoom = zoom,
size = paste0(size, collapse = "x"),
scale = scale,
maptype = maptype,
style = style,
key = api_key
)
url <- "https://maps.googleapis.com/maps/api/staticmap"
urltools::parameters(url) <- paste(names(params), params, sep = "=", collapse = "&")
url <- URLencode(url)
message("Souce: ", url)
img <- magick::image_read(httr::content(httr::GET(url)))
if (grayscale) img <- magick::image_quantize(img, colorspace = "gray")
ll <- RgoogleMaps::XY2LatLon(
list(lat = center[2], lon = center[1], zoom = zoom),
-size[1]/2 + 0.5, -size[2]/2 - 0.5
)
ur <- RgoogleMaps::XY2LatLon(
list(lat = center[2], lon = center[1], zoom = zoom),
size[1]/2 + 0.5, size[2]/2 - 0.5
)
structure(
as.raster(img), class = c("ggmap", "raster"),
source = "google", maptype = maptype, zoom = zoom,
bb = tibble::tibble(ll.lat = ll[1], ll.lon = ll[2], ur.lat = ur[1], ur.lon = ur[2])
)
}
I tried some specifications of size
and scale
with this new function and found out that the following specifications render the best map possible.
base_map <- get_googlemap2(
"Your API Key",
center = c(lon = -2.325278, lat = 54.6000000), zoom = 5, size = c(330, 380), scale = 2, style = 'element:labels|visibility:off', grayscale = TRUE
)
ggmap(base_map, extent = "panel")
Output
I hope this is what you want. I call this the best-possible result because if you attempt to further narrow the width, for example, down to 250, the attribution text will overlap with the logo.
base_map <- get_googlemap2(
"Your API Key",
center = c(lon = -2.325278, lat = 54.6000000), zoom = 5, size = c(250, 380), scale = 2, style = 'element:labels|visibility:off', grayscale = TRUE
)
ggmap(base_map, extent = "panel")
As far as I can tell, this is Google's problem, not ggmap
's. I have no way to solve it. Another workaround would be removing the attribution text from the image but reintroducing it as plain text within the content, as mentioned in Google's attribution guidlines. However, as Google's logo still needs to be there, you then have to figure out how to paste that onto the map. IMO, using plain text gives you greater flexibility in page layouts, and thus might be a better way to go.
I used a lot ggmap, and this type of problem I could not solve then in an elegant way. But there is a way to achieve something like what you want (doing kind of manually). With geom_rect
making the lightbox, and with geom_text
writing the copyright information.
ggmap(base_map, extent = "panel")+
scale_x_continuous(limits = c(-7, 3), expand = c(0, 0)) +
scale_y_continuous(limits = c(49.5, 59), expand = c(0, 0)) +
geom_rect(ymin = 49.5,ymax = 49.7, fill = 'white', alpha = 0.1, xmin = -3.35, xmax = 3) +
geom_text(y = 49.6, x = -0.2, size = 2.5,
label = 'Map data ©2020 GeoBasis-DE/BKG (©2009), Google, Inst. Geogr Nacional')
ggsave('Map.jpg', width = 7, height = 9, units = 'in')
The size and limits of geom_rect
and geom_text
must be edited manually according to the size of the save file. In this example, I provide the ggsave
I used for it and plot in a nice way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With