Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

locator equivalent in ggplot2 (for maps)

Tags:

r

ggplot2

ggmap

Note: This question is specific for mapping but I'd like to be able to use it when I plot in a standard Cartesian coordinate system.

I love base graphics but also like ggplot2 for many things. One of my most used base functions for fine tuning a graph is locator(n) but this produces an error in ggplot2.

library(ggplot2)  county_df <- map_data('county')  #mappings of counties by state ny <- subset(county_df, region=="new york")   #subset just for NYS ny$county <- ny$subregion  ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA) locator(1) 

Now grid.locator() as pointed out to me by Dason on talkstats.com (HERE) can return something. I just don't know how to use that something to get a map coordinate.

> grid.locator() $x [1] 286native  $y [1] 133native 

Units didn't seem to help as they are not map coordinates. Maybe I need some sort of conversion.

Thank you in advance.

EDIT: (based on DWin's response)

Dwin's got the right idea but the conversion factor is a little bit off. Help with that would be appreciated. In the example below I have a map with a red dot on it at the coordinates (x = -73 & y = 40.855). I threw Dwin's response into a function to return the coordinates. I would expect the results to be the coordinates I put in but they're not.

Ideas?

require(maps); library(ggplot2); require(grid)  county_df <- map_data('county')  #mappings of counties by state ny <- subset(county_df, region=="new york")   #subset just for NYS ny$county <- ny$subregion   NY <- ggplot(ny, aes(long, lat)) +             geom_polygon(aes(group=group), colour='black', fill=NA) +           coord_map() + geom_point(aes(-73, 40.855, colour="red")) NY    gglocator <- function(object){     require(maps); require(grid)     z <- grid.locator("npc")     y <- sapply(z, function(x) as.numeric(substring(x, 1, nchar(x))))     locatedX <- min(object$data$long) + y[1]*diff(range(object$data$long))     locatedy <- min(object$data$lat)  + y[2]*diff(range(object$data$lat))     return(c(locatedX, locatedy)) }  #click on the red dot gglocator(NY)  #I expect the results to be x = -73 & y = 40.855 

EDIT 2: (Going off of Baptise's answer)

We're there

NY <- ggplot(ny, aes(long, lat)) +             geom_polygon(aes(group=group), colour='black', fill=NA) +           coord_map() + geom_point(aes(-73, 40.855, colour="red")) +           scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0))   NY  x <- grid.ls()[[1]][grep("panel-", grid.ls()[[1]])] #locate the panel seekViewport(x) y <-  grid.locator("npc") y <- as.numeric(substring(y, 1, nchar(y)-3))  locatedX <- min(NY$data$long) + y[1]*diff(range(NY$data$long)) locatedy <- min(NY$data$lat) + y[2]*diff(range(NY$data$lat)) locatedX; locatedy  

UPDATE: The gglocator function of the ggmap package now contains this functionality.

like image 295
Tyler Rinker Avatar asked Feb 26 '12 05:02

Tyler Rinker


People also ask

How do I create a map in ggplot2?

The easiest way to create spatial plots with ggplot is to use the geom_sf() function. By default there is no aesthetic mapping, but we can use arguments like fill to easily create choropleth maps.

What is GG in ggplot?

ggplot2 is a system for declaratively creating graphics, based on The Grammar of Graphics. You provide the data, tell ggplot2 how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.


2 Answers

Need to use a unit system that makes sense and save the information in the ggplot object so you can convert from "npc" units to map units:

require(maps) require(grid) NY <- ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA)  grid.locator("npc") # clicked in middle of NY State:  #$x #[1] 0.493649231346082npc # #$y #[1] 0.556430446194226npc  range(NY$data$long) #[1] -79.76718 -71.87756  range(NY$data$lat) #[1] 40.48520 45.01157  locatedX <- min(NY$data$long) + 0.493649231346082*diff(range(NY$data$long))  locatedX #[1] -75.87247 locatedY <- min(NY$data$lat) +  0.556430446194226*diff(range(NY$data$lat)) locatedY #[1] 43.00381 
like image 51
IRTFM Avatar answered Sep 27 '22 15:09

IRTFM


I get the correct result if I add scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0)) to the plot, and seekViewport("panel-3-4") before grid.locator()

like image 43
baptiste Avatar answered Sep 27 '22 17:09

baptiste