注意:这个问题是专门用于映射的,但我希望能够在标准笛卡尔坐标系中绘图时使用它。
我喜欢基本图形,但也喜欢ggplot2。用于微调图形的最常用的基本函数之一是locator(n),但这会在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)
现在grid.locator()
由Dason在talkstats.com(HERE)指出我可以回复一些东西。我只是不知道如何使用那些东西来获得地图坐标。
> grid.locator()
$x
[1] 286native
$y
[1] 133native
单位似乎没有帮助,因为它们不是地图坐标。也许我需要某种转换。
提前谢谢。
编辑:(基于DWin的回复)
Dwin有正确的想法,但转换因素有点偏。对此的帮助将不胜感激。在下面的示例中,我在坐标处有一个红点(x = -73&amp; y = 40.855)。我把Dwin的响应扔进了一个函数来返回坐标。我希望结果是我输入的坐标,但它们不是。
想法?
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
编辑2 :(脱离Baptise的回答)
我们在那里
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
更新: ggmap package的gglocator
功能现在包含此功能。
答案 0 :(得分:9)
需要使用有意义的单位系统并将信息保存在ggplot对象中,以便您可以转换为&#34; npc&#34;单位来映射单位:
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
答案 1 :(得分:7)
如果我将scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0))
添加到地块中,我会得到正确的结果,seekViewport("panel-3-4")
之前grid.locator()
答案 2 :(得分:5)
这是使用DWin和Baptise给我包装成函数的所有内容的最终结果。我还询问了ggplot帮助列表,并将在此处报告和提供其他信息。
require(maps); require(ggplot2); require(grid)
ny <- map_data('county', 'new york')
NY1 <- ggplot(ny, aes(long, lat)) +
geom_polygon(aes(group=group), colour='black', fill=NA) +
coord_map() + geom_point(aes(c(-78, -73), c(41, 40.855),
colour=c("blue", "red"))) + opts(legend.position = "none")
NY <- NY1 + scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0))
#the scale x and y have to be added to the plot
NY
ggmap.loc <- function(object){
x <- grid.ls()[[1]][grep("panel-", grid.ls()[[1]])] #locate the panel
seekViewport(x)
y <- as.numeric(grid.locator("npc"))
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))
}
ggmap.loc(NY)
答案 3 :(得分:5)
我写信给ggplot帮助列表并收到David Kahle的非常有用的回复,他恰好对同样的问题感兴趣。他的功能很棒:
1)您不必添加比例y并将x缩放到图
2)它可以一次找到多个点并将它们作为数据框返回
3)它适用于任何类型的ggplot,而不仅仅是地图
gglocator <- function(n = 1, object = last_plot(),
message = FALSE, xexpand = c(.05,0), yexpand = c(.05, 0)){
#compliments of David Kahle
if(n > 1){
df <- NULL
for(k in 1:n){
df <- rbind(df, gglocator(object = object, message = message,
xexpand = xexpand, yexpand = yexpand))
}
return(df)
}
x <- grid.ls(print = message)[[1]]
x <- x[ grep("panel-", grid.ls(print=message)[[1]]) ] #locate the panel
seekViewport(x)
loc <- as.numeric(grid.locator("npc"))
xrng <- with(object, range(data[,deparse(mapping$x)]))
yrng <- with(object, range(data[,deparse(mapping$y)]))
xrng <- expand_range(range = xrng, mul = xexpand[1], add = xexpand[2])
yrng <- expand_range(range = yrng, mul = yexpand[1], add = yexpand[2])
point <- data.frame(xrng[1] + loc[1]*diff(xrng), yrng[1] + loc[2]*diff(yrng))
names(point) <- with(object, c(deparse(mapping$x), deparse(mapping$y)))
point
}
#Example 1
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(c(-78, -73), c(41, 40.855),
colour=c("blue", "red"))) + opts(legend.position = "none")
NY
gglocator(2)
#Example 2
df <- data.frame(xvar = 2:10, yvar = 2:10)
ggplot(df, aes(xvar, yvar)) + geom_point() + geom_point(aes(x = 3, y = 6))
gglocator()
更新: ggmap package的gglocator
功能现在包含此功能。
答案 4 :(得分:3)
这些帖子非常有用,但已经过了几年,所以有些事情被打破了。这是一些适合我的新代码。找到正确视口的代码不起作用,因此我使用current.vpTree()
手动搜索右视口,然后将其复制到seekViewport()
。请注意,我的视口是'panel.6-4-6-4'
,而不是旧样式panel-*
。最后,我在rstudio中渲染时没有得到正确的答案,而是我必须使用x11()
。
这是一个完整的例子。希望这有用。
library(ggplot2)
library(grid)
object<-ggplot(dat=data.frame(x=1:5,y=1:5),aes(x=x,y=y)) +
geom_point() +
scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0))
x11()
print(object)
formatVPTree(current.vpTree()) #https://www.stat.auckland.ac.nz/~paul/useR2015-grid/formatVPTree.R
seekViewport('panel.6-4-6-4')
y <- as.numeric(grid.locator("npc"))
locatedX <- min(object$data$x) + y[1]*diff(range(object$data$x))
locatedY <- min(object$data$y) + y[2]*diff(range(object$data$y))
locatedX; locatedY