I am using ggmap and wish to have a map of the world centered on Australia to which I can easily plot geocoded points. ggmap seems to be a lot easier to use compared to some
EDIT: Updated to ggplot2 v 0.9.3
I tried something similar recenty but with little success. However, there are a number of ways to centre a world map from the map
package: see here, here, and here. Using code from the latter, here's an example that centers the world map on longitude 160, plots CRAN mirror locations (coordinates obtained using the geocode()
function from the ggmap package) on the world map plotted using ggplot2, and colours New Zealand (using geom_polygon
). Centering the map on longitude 160 keep all of Africa on the left of the map, and most of Greenland on the right of the map.
library(maps)
library(plyr)
library(ggplot2)
library(sp)
library(ggmap)
# Get some points to plot - CRAN Mirrors
Mirrors = getCRANmirrors(all = FALSE, local.only = FALSE)
Mirrors$Place = paste(Mirrors$City, ", ", Mirrors$Country, sep = "") # Be patient
tmp = geocode(Mirrors$Place)
Mirrors = cbind(Mirrors, tmp)
###################################################################################################
# Recentre worldmap (and Mirrors coordinates) on longitude 160
### Code by Claudia Engel March 19, 2012, www.stanford.edu/~cengel/blog
### Recenter ####
center <- 160 # positive values only
# shift coordinates to recenter CRAN Mirrors
Mirrors$long.recenter <- ifelse(Mirrors$lon < center - 180 , Mirrors$lon + 360, Mirrors$lon)
# shift coordinates to recenter worldmap
worldmap <- map_data ("world")
worldmap$long.recenter <- ifelse(worldmap$long < center - 180 , worldmap$long + 360, worldmap$long)
### Function to regroup split lines and polygons
# Takes dataframe, column with long and unique group variable, returns df with added column named group.regroup
RegroupElements <- function(df, longcol, idcol){
g <- rep(1, length(df[,longcol]))
if (diff(range(df[,longcol])) > 300) { # check if longitude within group differs more than 300 deg, ie if element was split
d <- df[,longcol] > mean(range(df[,longcol])) # we use the mean to help us separate the extreme values
g[!d] <- 1 # some marker for parts that stay in place (we cheat here a little, as we do not take into account concave polygons)
g[d] <- 2 # parts that are moved
}
g <- paste(df[, idcol], g, sep=".") # attach to id to create unique group variable for the dataset
df$group.regroup <- g
df
}
### Function to close regrouped polygons
# Takes dataframe, checks if 1st and last longitude value are the same, if not, inserts first as last and reassigns order variable
ClosePolygons <- function(df, longcol, ordercol){
if (df[1,longcol] != df[nrow(df),longcol]) {
tmp <- df[1,]
df <- rbind(df,tmp)
}
o <- c(1: nrow(df)) # rassign the order variable
df[,ordercol] <- o
df
}
# now regroup
worldmap.rg <- ddply(worldmap, .(group), RegroupElements, "long.recenter", "group")
# close polys
worldmap.cp <- ddply(worldmap.rg, .(group.regroup), ClosePolygons, "long.recenter", "order") # use the new grouping var
#############################################################################
# Plot worldmap using data from worldmap.cp
windows(9.2, 4)
worldmap = ggplot(aes(x = long.recenter, y = lat), data = worldmap.cp) +
geom_polygon(aes(group = group.regroup), fill="#f9f9f9", colour = "grey65") +
scale_y_continuous(limits = c(-60, 85)) +
coord_equal() + theme_bw() +
theme(legend.position = "none",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
#axis.text.x = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.border = element_rect(colour = "black"))
# Plot the CRAN Mirrors
worldmap = worldmap + geom_point(data = Mirrors, aes(long.recenter, lat),
colour = "red", pch = 19, size = 3, alpha = .4)
# Colour New Zealand
# Take care of variable names in worldmap.cp
head(worldmap.cp)
worldmap + geom_polygon(data = subset(worldmap.cp, region == "New Zealand", select = c(long.recenter, lat, group.regroup)),
aes(x = long.recenter, y = lat, group = group.regroup), fill = "blue")
Check out ggplot's inbuilt coord_map. This can create maps without requiring a third party set of tiles. Its great for simple maps and can use all of the beauty that is ggplot.
http://docs.ggplot2.org/current/coord_map.html
I have managed to build world map based on Google Maps. This is unfortunately slightly distorted, as I believe ggmap/Google Maps imposes restrictions (data length = 409600 pixels, with dimension being a multiple of 792). Nevertheless, the following combination of size, scale and zoom parameters delivers Google world map with ggmap.
Natrally, you can alter lon
to change the point of longitudal focus to Australia, as you wish.
library(tidyverse)
your_gmaps_API_key <- ""
get_googlemap(center = c(lon = 0, lat = 0)
, zoom = 1
, maptype="roadmap"
, size = c(512,396)
, scale = 2
, color = "bw"
, key = your_gmaps_API_key) %>% ggmap(.)
Note: points on the map are from my own dataset and not produced by the code above, but the world map is of core importance here.
I recently got the same error and it boiled down to ggmap not liking latitudes outside $\pm$ 80°.
However, I had to download my image separately as it was too large for a download (with OSM); this is not your problem, but I record it for future readers.
Here's how I solved it:
cbind
. Just make sure you know the longitude of your cut.Here's what I do:
require ("ggmap")
library ("png")
zoom <- 2
map <- readPNG (sprintf ("mapquest-world-%i.png", zoom))
map <- as.raster(apply(map, 2, rgb))
# cut map to what I really need
pxymin <- LonLat2XY (-180,73,zoom+8)$Y # zoom + 8 gives pixels in the big map
pxymax <- LonLat2XY (180,-60,zoom+8)$Y # this may or may not work with google
# zoom values
map <- map [pxymin : pxymax,]
# set bounding box
attr(map, "bb") <- data.frame (ll.lat = XY2LonLat (0, pxymax + 1, zoom+8)$lat,
ll.lon = -180,
ur.lat = round (XY2LonLat (0, pxymin, zoom+8)$lat),
ur.lon = 180)
class(map) <- c("ggmap", "raster")
ggmap (map) +
geom_point (data = data.frame (lat = runif (10, min = -60 , max = 73),
lon = runif (10, min = -180, max = 180)))
result:
Edit: I played a bit around with your google map, but I didn't get the latitudes correct. :-(