2

I am trying to create an image similar to that presented by Ricardo Bion of Airbnb but I would like to plot the visualization over the NASA "black marble" image to give more context as I don't have nearly the data density of the Airbnb dataset.

I downloaded the Nasa black marble image here using the global map 13500x6750 (3km) GeoTIFF 39 MB option.

This issue I keep running into is most of the options and explanations available online have been depreciated in the past few years. I tried using EBImage as shown here but ebimageGrob has been removed from gridExtra. I also tried to use the rasterVis package as shown here but the code breaks at the colorable step.

Here is as far as I have made it trying to layer the tiff behind the plot using the ggplot2 annotation_raster option (this gives the lines between the destinations but only a white background):

library(ggplot2)
library(ggmap)
library(sp)
library(grid)
library(geosphere)
library(plyr)
library(tiff)

# source the theme_map for ggplot2
# source("https://dl.dropboxusercontent.com/u/2364714/theme_map.R")

# in the original post I had a data.frame with 500k rows of top origin destination pairs
trips <- data.frame(origin = c("San Francisco", "Sydney", "Chicago"), 
                destination = c("Paris", "Tokyo", "Boston"), 
                stringsAsFactors = FALSE)


# get lat and lon of cities
trips$geocode_origin <- suppressMessages(geocode(trips$origin))
trips$geocode_destination <- suppressMessages(geocode(trips$destination))


# get intermediate points between the two locations
arch <- gcIntermediate(trips$geocode_origin,
                   trips$geocode_destination,
                   n=100,
                   breakAtDateLine=FALSE, 
                   addStartEnd=TRUE, sp=TRUE)

# http://docs.ggplot2.org/0.9.3.1/fortify.map.html
arch_fortified <- ldply(arch@lines, fortify)

earth <- readTIFF("~/Downloads/dnb_land_ocean_ice.2012.13500x6750_geo.tif")

theme_map <- function(base_size = 12) {
  require(grid)
  theme_grey(base_size) %+replace%
    theme(
      axis.title = element_blank(),
      axis.text = element_blank(),
      panel.grid = element_blank(),
      axis.ticks.length = unit(0,"cm"),
      panel.margin = unit(0,"lines"),
      plot.margin = unit(c(0,0,0,0),"lines"),
      complete = TRUE, 
      panel.background = element_rect(fill = NA, colour=NA)
    )
}

# a few lines of ggplot2 code
ggplot() +
  geom_line(aes(long,lat,group=group), data=arch_fortified, alpha=0.1,size=1, colour="skyblue1") +
  coord_cartesian(ylim =c(-45, 70), xlim=c(-165, 165)) +
  theme_map() +
  geom_point(aes(lon, lat),data=trips$geocode_origin, alpha = 0.8, size = 1, colour = "white") +
  geom_point(aes(lon, lat),data=trips$geocode_destination, alpha = 0.8, size = 1, colour = "white") + 
  annotation_raster(earth, -180, 180, -90, 90)

Thanks!

Community
  • 1
  • 1
EpiBlake
  • 177
  • 1
  • 12

1 Answers1

1

I just had to slightly modify your plotting code to get it work:

ggplot(arch_fortified) +
  coord_cartesian(ylim =c(-45, 70), xlim=c(-165, 165)) +
  theme_map() +
  annotation_raster(earth, -180, 180, -90, 90) +
  geom_line(aes(long,lat,group=group), alpha=0.1,size=1, colour="skyblue1") +
  geom_point(aes(lon, lat),data=trips$geocode_origin, alpha = 0.8, size = 1, colour = "white") +
  geom_point(aes(lon, lat),data=trips$geocode_destination, alpha = 0.8, size = 1, colour = "white") 

Note that you should first draw the background and only then the lines and points, otherwise the image will cover other plot elements.

aoles
  • 1,525
  • 10
  • 17