将指北针和比例尺添加到 ggmap 的简约方法
Parsimonious way to add north arrow and scale bar to ggmap
我正在尝试使用 ggmap 创建我正在工作的保护区的地图以及来自下方 google 地球的卫星图像。我可以做出非常满意的图像,只是缺少指北针和比例尺:
我知道添加这些元素的方法非常冗长(例如 here),但肯定有更简洁的方法来添加这些元素!
我试过使用 map.scale
和 north.arrow
但这些都给我:
Error in polygon(xb + arrow.x * s, yb + arrow.y * s, ...) :
plot.new has not been called yet
我可以使用 plot
让 map.scale
和 north.arrow
在 base R 中工作,但是我无法正确绘制我的卫星图像。我也可以在 base R 中使用 arrows
和 text
得到我想要的东西,但同样这些在 ggmap 中不起作用。
我使用的代码如下。你不会有多边形(所以我不会在代码中包含它)但你将能够加载 google 地球图像并复制错误。
library(rgdal)
library(ggmap)
library(GISTools)
# Load satellite picture
map.centre <- c(lon = 35, lat = -2.5)
map <- get_map(location=map.centre, source="google", maptype="satellite", zoom = 8)
# Plot map
ggmap(map, extent= "device")
map.scale(xc= 34, yc= -3, len= 10, units= "Kilometers",
ndivs= 4, tcol= "black", scol= "black", sfcol="black")
north.arrow(xb= 35.5, yb= -1, len=100, lab="N")
通过一些阅读,map.scale
和 north.arrow
函数似乎无法识别 window ggmap
函数创建为一个开放的图形 window。我做了一些研究并试图解决这个问题,但没有任何效果。有没有人能建议一种方法来修复我收到的错误或在不使用数百行代码的情况下在 ggmap 中获得比例尺和指北针?
看起来 map.scale
和 north.arrow
设计用于处理基础图形,但 ggplot 使用 grid
图形。我不太熟悉绘制空间数据,但作为指北针的快速破解,下面的代码包含两个不同的选项:
ggmap(map, extent= "device") +
geom_segment(arrow=arrow(length=unit(3,"mm")), aes(x=33.5,xend=33.5,y=-2.9,yend=-2.6),
colour="yellow") +
annotate(x=33.5, y=-3, label="N", colour="yellow", geom="text", size=4) +
geom_segment(arrow=arrow(length=unit(4,"mm"), type="closed", angle=40),
aes(x=33.7,xend=33.7,y=-2.7,yend=-2.6), colour=hcl(240,50,80)) +
geom_label(aes(x=33.7, y=-2.75, label="N"),
size=3, label.padding=unit(1,"mm"), label.r=unit(0.4,"lines"))
我倾向于使用自己的函数在 ggmaps 上绘制比例尺。这使您可以精确地控制它以您想要的方式进行布局。例如,
scalebar = function(x,y,w,n,d, units="km"){
# x,y = lower left coordinate of bar
# w = width of bar
# n = number of divisions on bar
# d = distance along each division
bar = data.frame(
xmin = seq(0.0, n*d, by=d) + x,
xmax = seq(0.0, n*d, by=d) + x + d,
ymin = y,
ymax = y+w,
z = rep(c(1,0),n)[1:(n+1)],
fill.col = rep(c("black","white"),n)[1:(n+1)])
labs = data.frame(
xlab = c(seq(0.0, (n+1)*d, by=d) + x, x),
ylab = c(rep(y-w*1.5, n+2), y-3*w),
text = c(as.character(seq(0.0, (n+1)*d, by=d)), units)
)
list(bar, labs)
}
sb = scalebar(33.5, -3.8, 0.05, 5, 0.3, "degrees" )
# Plot map
ggmap(map, extent= "device") +
geom_rect(data=sb[[1]], aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=z), inherit.aes=F,
show.legend = F, color = "black", fill = sb[[1]]$fill.col) +
geom_text(data=sb[[2]], aes(x=xlab, y=ylab, label=text), inherit.aes=F, show.legend = F)
我正在尝试使用 ggmap 创建我正在工作的保护区的地图以及来自下方 google 地球的卫星图像。我可以做出非常满意的图像,只是缺少指北针和比例尺:
我知道添加这些元素的方法非常冗长(例如 here),但肯定有更简洁的方法来添加这些元素!
我试过使用 map.scale
和 north.arrow
但这些都给我:
Error in polygon(xb + arrow.x * s, yb + arrow.y * s, ...) :
plot.new has not been called yet
我可以使用 plot
让 map.scale
和 north.arrow
在 base R 中工作,但是我无法正确绘制我的卫星图像。我也可以在 base R 中使用 arrows
和 text
得到我想要的东西,但同样这些在 ggmap 中不起作用。
我使用的代码如下。你不会有多边形(所以我不会在代码中包含它)但你将能够加载 google 地球图像并复制错误。
library(rgdal)
library(ggmap)
library(GISTools)
# Load satellite picture
map.centre <- c(lon = 35, lat = -2.5)
map <- get_map(location=map.centre, source="google", maptype="satellite", zoom = 8)
# Plot map
ggmap(map, extent= "device")
map.scale(xc= 34, yc= -3, len= 10, units= "Kilometers",
ndivs= 4, tcol= "black", scol= "black", sfcol="black")
north.arrow(xb= 35.5, yb= -1, len=100, lab="N")
通过一些阅读,map.scale
和 north.arrow
函数似乎无法识别 window ggmap
函数创建为一个开放的图形 window。我做了一些研究并试图解决这个问题,但没有任何效果。有没有人能建议一种方法来修复我收到的错误或在不使用数百行代码的情况下在 ggmap 中获得比例尺和指北针?
看起来 map.scale
和 north.arrow
设计用于处理基础图形,但 ggplot 使用 grid
图形。我不太熟悉绘制空间数据,但作为指北针的快速破解,下面的代码包含两个不同的选项:
ggmap(map, extent= "device") +
geom_segment(arrow=arrow(length=unit(3,"mm")), aes(x=33.5,xend=33.5,y=-2.9,yend=-2.6),
colour="yellow") +
annotate(x=33.5, y=-3, label="N", colour="yellow", geom="text", size=4) +
geom_segment(arrow=arrow(length=unit(4,"mm"), type="closed", angle=40),
aes(x=33.7,xend=33.7,y=-2.7,yend=-2.6), colour=hcl(240,50,80)) +
geom_label(aes(x=33.7, y=-2.75, label="N"),
size=3, label.padding=unit(1,"mm"), label.r=unit(0.4,"lines"))
我倾向于使用自己的函数在 ggmaps 上绘制比例尺。这使您可以精确地控制它以您想要的方式进行布局。例如,
scalebar = function(x,y,w,n,d, units="km"){
# x,y = lower left coordinate of bar
# w = width of bar
# n = number of divisions on bar
# d = distance along each division
bar = data.frame(
xmin = seq(0.0, n*d, by=d) + x,
xmax = seq(0.0, n*d, by=d) + x + d,
ymin = y,
ymax = y+w,
z = rep(c(1,0),n)[1:(n+1)],
fill.col = rep(c("black","white"),n)[1:(n+1)])
labs = data.frame(
xlab = c(seq(0.0, (n+1)*d, by=d) + x, x),
ylab = c(rep(y-w*1.5, n+2), y-3*w),
text = c(as.character(seq(0.0, (n+1)*d, by=d)), units)
)
list(bar, labs)
}
sb = scalebar(33.5, -3.8, 0.05, 5, 0.3, "degrees" )
# Plot map
ggmap(map, extent= "device") +
geom_rect(data=sb[[1]], aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=z), inherit.aes=F,
show.legend = F, color = "black", fill = sb[[1]]$fill.col) +
geom_text(data=sb[[2]], aes(x=xlab, y=ylab, label=text), inherit.aes=F, show.legend = F)