我有一个像这样的数据框
id lon lat
1 A -69.5 -58.5
2 A -69.5 -58.5
3 A -69.5 -57.5
4 A -68.5 -57.5
5 A -68.5 -57.5
6 A -68.5 -57.5
7 A -66.5 -57.5
8 A -68.5 -56.5
9 A -68.5 -56.5
10 A -67.5 -56.5
11 A -65.5 -56.5
12 A -65.5 -56.5
13 A -65.5 -55.5
14 A -62.5 -54.5
15 B -177 -52.5
16 B -178 -50.5
17 B -179 -48.5
18 B 179 -47.5
19 B 178 -46.5
20 B 177 -46.5
我希望生成一个A和B位置的地图,由定向线链接。然而,当ids穿越太平洋时(lon = -180 - > lon = + 180),我会得到一个箭头穿过整个数字,如下图所示。
这是我正在使用的代码
worldmap = map_data("world")
ggplot(test, aes(x = lon, y=lat, colour = factor(id))) +
geom_polygon(data=worldmap,center=180,aes(x=long, y=lat, group=group), fill="black",colour="black") +
xlab("") +ylab("")+theme(axis.text=element_blank(),axis.ticks=element_blank())+ theme(panel.background = element_rect(fill = 'white', colour = 'black') ,panel.grid.major = element_blank(),panel.grid.minor = element_blank())+
geom_path(size =2,arrow = arrow(angle=30,length = unit(0.6, "inches")))
我该如何解决?
由于
答案 0 :(得分:1)
我想这取决于你认为“正确”的想法。我决定通过在地图边缘添加点来分解穿过glob的两个段,然后创建一个“序列”指示器,以便ggplot知道要连接哪些行。这是您的样本数据的转换
test2 <- do.call(rbind, lapply(split(test, test$id), function(x) {
cp <- cumsum(c(FALSE, diff(x$lon)>250))
xx<-split(x, cp)
xx<-Map(cbind, xx, seq=seq_along(xx))
Reduce(function(a,b) {
lasta<-a[nrow(a),]
firstb<-b[1,]
lasta$lon <- 180*sign(lasta$lon)
firstb$lon <- 180*sign(firstb$lon)
lasta$lat <- mean(lasta$lat, firstb$lat)
firstb$lat <- lasta$lat
rbind(a,lasta, firstb,b)
}, xx)
}))
tail(test2)
# id lon lat seq
# B.17 B -179 -48.5 1
# B.171 B -180 -48.5 1
# B.18 B 180 -48.5 2
# B.181 B 179 -47.5 2
# B.19 B 178 -46.5 2
# B.20 B 177 -46.5 2
在这里你可以看到我们已经将B线分成两个序列。那么如果我们使用群体美学
geom_path(aes(group=interaction(id, seq)), ...)
然后R只会连接同一个id / seq组中的那些点。这将阻止该线穿过海洋。但是,因为我们为该组绘制了两条线而不是一条线,所以没有办法只为其中一个线段转动箭头。您可能想要找到另一种表示开始/结束的方式。