Search code examples
rggmap

Overlay worldmap in R with rgeolocate plot


In my previous question, I presented that I have a table of "posts" with IPs, and that I wanted to geolocate them. Geolocating a large number of posts based on IP Addresses. (880,000 rows)

The answer demonstrated how to use rgeolocate to achieve this, and after some effort in learning R I have managed to accomplish the same result:

library(iptools)
library(rgeolocate)
library(tidyverse)
library(readxl)
library(rworldmap)
library(ggmap)
library(rworldxtra)
post <- read_excel("filepath/post.xlsx")
view(post)

## grab my ips and, format them

ips <- unlist(post[,3], use.names=FALSE)

#geolocte them
system.time(
rgeolocate::maxmind(
ips, "~/R/GeoLite2-City.mmdb", c("longitude", "latitude")
) -> xdf
)

#user  system elapsed 
#6.04    0.02    6.05 

xdf %>% 
  count(longitude, latitude) -> pts

#And, plot them:
  ggplot(pts) +
  geom_point(
    aes(longitude, latitude, size = n), 
    shape=21, fill = "steelblue", color = "white", stroke=0.25
  ) +
  ggalt::coord_proj("+proj=wintri") +
  ggthemes::theme_map() +
  theme(legend.justification = "center") +
  theme(legend.position = "bottom")

The result is shown here:

plot of ips

This plot shows exactly the sort of grouping that I would expect, based on the data. So one step of success!

Of course, the next logical step is to increase the resolution and add an overlay of a world map. I have been unable to achieve either of these goals.

Using this code, I can make a high resolution world map:

newmap <- getMap(resolution = "high")
plot(newmap)

And the result is shown here:

worldmap no points

Somehow I just can't achieve a combination of the map AND the data being plotted. It seems like any attempt to create the map needs me to plot the map itself, and any attempt to add points to that fail. For example:

newmap <- getMap(resolution = "high")
plot(newmap)
ggmap(newmap) +
  geom_point(data = pts, aes(x = longitude, y = latitude, size=n), 
             shape=21, fill = "steelblue", color = "white", stroke=0.25)

Error: ggmap plots objects of class ggmap, see ?get_map

I have been trying to work based on the advice of http://www.milanor.net/blog/maps-in-r-plotting-data-points-on-a-map/ but this website focuses on a map of Europe, and I want to show my data on a map of the world.

Thank you for your help.


Solution

  • library(iptools)
    library(rgeolocate)
    library(tidyverse)
    
    ips <- ip_random(1000000)
    
    rgeolocate::maxmind(
      ips, "~/Data/GeoLite2-City.mmdb", c("longitude", "latitude")
    ) -> xdf
    
    xdf %>% 
      mutate(
        longitude = (longitude %/% 5) * 5,
        latitude = (latitude %/% 5) * 5
      ) %>%  
      count(longitude, latitude) -> pts
    
    wrld <- tbl_df(map_data("world"))
    wrld <- filter(wrld, region != "Antarctica")
    
    ggplot() +
      geom_map(
        map = wrld, data = wrld, aes(long, lat, map_id=region),
        color = "black", fill ="white", size=0.125
      ) +
      geom_point(
        data = pts, aes(longitude, latitude, size = n), 
        shape=21, fill = "steelblue", color = "white", stroke=0.25
      ) +
      scale_size(name = "# IPs", label=scales::comma) +
      ggalt::coord_proj("+proj=wintri") +
      ggthemes::theme_map() +
      theme(legend.justification = "center") +
      theme(legend.position = "bottom")
    

    enter image description here