Tito Sanz
Tito Sanz

Reputation: 1362

From rastermap package to ggplot2

My problem: I want to draw a map obtained via rastermap package with ggplot2.

Searching for alternatives to ggmap package I found the rastermap package which provides an easy way to obtain maps from external sources. The readme provides a very simple example:

# install.packages("devtools")
devtools::install_github("hadley/rastermap")

houston <- fetch_region(c(-95.80204, -94.92313), c(29.38048, 30.14344),
  stamen("terrain"))
houston
plot(houston)

The problem comes whether I try to plot using ggplot. So far I've tried several ways but none of them seems to work. Is it possible? Any idea?

Upvotes: 1

Views: 302

Answers (2)

dww
dww

Reputation: 31452

rastermap generates a matrix of colours in hexadecimal strings (#RRGGBB format). It may be simplest to convert this to a more common form for spatial data, a multiband raster brick, with separate layers for the red, green and blue.

We can write a short helper function to convert hexadecimal strings into the separate integer values (i.e. this is the reverse of the rgb() function):

un_rgb = function (x) {
  x = unlist(str_split(x, ''))
  r = paste0(x[2], x[3])
  g = paste0(x[4], x[5])
  b = paste0(x[6], x[7])
  strtoi(c(r,g,b), 16)
}

Using this function we convert the rastermap matrix into a three band raster brick:

library(raster)    
m = as.matrix(houston)
l=lapply(m[], un_rgb)
r=g=b=matrix(, dim(m)[1], dim(m)[2])
r[] = sapply(l, function(i) i[1])
g[] = sapply(l, function(i) i[2])
b[] = sapply(l, function(i) i[3])
rgb.brick = brick(raster(r), raster(g), raster(b))

And set the extent of the new raster to that of the original rastermap

extent(rgb.brick) = extent(matrix(unlist(attributes(houston)$bb), nrow=2))

Now that we have a more usual form of raster object, we can do various things with it. For example, we can plot it in ggplot using library(RStoolbox):

ggRGB(rgb.brick, r=1, g=2, b=3)

enter image description here

Or we can save it as an image to use as an annotation background in ggplot:

png('test.png', dim(rgb.brick)[2], dim(rgb.brick)[1])
  plotRGB(rgb.brick, 1, 2, 3)
dev.off()

img <- png::readPNG("test.png")
gr <- grid::rasterGrob(img, interpolate=TRUE)
ggplot() + annotation_custom(gr, -Inf, Inf, -Inf, Inf)

enter image description here

Upvotes: 1

Roman
Roman

Reputation: 4989

Why would you want an alternative? You can get a stamen map from :

library(ggmap)
ggmap(get_stamenmap(c(-95.80204, 29.38048, -94.92313, 30.14344))) +
# some points to plot
geom_point(aes(x = seq(-95.5, -95.2, 0.1), y = seq(29.7, 30, 0.1)), color = "red")

1

Upvotes: 0

Related Questions