ggplot2:将基本海岸线添加到地图

ggplot2: Add basic coastlines to a map

我在海洋学背景下使用 ggplot2,我想添加一张简单的陆地地图以供参考。这是基本图形中的最小工作示例:

library(ggplot2)
library(maps)

#Setup fake data - some points in the North Sea
n <- 100
d <- data.frame(lon=rnorm(n,5),lat=rnorm(n,55))

#Plotting with base-graphics, then overlaying map
plot(lat~lon,d,pch=16,col="red",asp=1)
map("world",add=TRUE,col="black",fill=TRUE)

请注意,此图的 xlim 和 ylim 由数据范围设置。

现在,尝试在 ggplot 中重现:

#And now with ggplot
g <- ggplot(d,aes(lon,lat))+geom_point(col="red",pch=16)+
     borders("world",fill="black",colour="black")
plot(g)

...这在技术上是正确的 - 轴设置为覆盖所有点 - 但并不是我真正想要的。

我当然可以进入并使用例如手动设置轴coord_cartesian 或类似的,但这具有很高的刺激因素 - 特别是在尝试自动生成大量类似地图时。理想情况下,我希望能够覆盖 borders/coastlines 并告诉 ggplot 在确定轴时不要考虑它们。或者,我的印象是 geom_map map 是前进的方向,但我并没有取得太大的成功..

有什么建议吗?

马克

使用 ggmap 的替代方法,您可以手动或迭代获取所需区域的地图:

library(ggmap)
northseamap <- get_map(location = "north sea", zoom=6)
g <- ggmap(northseamap) +geom_point(data = d, aes(x=lon, y=lat), col="red",pch=16)
g

这会产生以下地图:

请注意,您为一个 google 查询 ('north sea') 或一对 lat/lon 点交易设置两个坐标。

相同(相似)的地图,为位置传递了一对点(来自数据):

northseamap2 <- get_map(location = c(lon = mean(d$lon), lat = mean(d$lat)), zoom=6)
g <- ggmap(northseamap2) +geom_point(data = d, aes(x=lon, y=lat), col="red",pch=16)
g

以下这个版本更接近你原来情节的精神(尽管有一个实际黑海):

northseamap3 <- get_map(location = c( lon = mean(d$lon), lat = mean(d$lat)),source="stamen", color="bw", zoom=6, maptype="toner")
g <- ggmap(northseamap3) +geom_point(data = d, aes(x=lon, y=lat), col="red",pch=16)
g

使用 ggplot 绝对可行,但您需要它的朋友的一些帮助,因为您是正确的 geom_map 需要获得美观的结果。

library(ggplot2)
library(ggthemes)
library(maps)
require(sp)
require(maptools)

# your data

n <- 100
set.seed(1492) # makes the results reproducible
d <- data.frame(lon=rnorm(n, 5),
                lat=rnorm(n, 55))

# get the map, don't plot it but `fill` gets us named 'map' polygons
world <- map("world", fill=TRUE, plot=FALSE)

# convert the 'map' to something we can work with via geom_map
IDs <- sapply(strsplit(world$names, ":"), function(x) x[1])
world <- map2SpatialPolygons(world, IDs=IDs, proj4string=CRS("+proj=longlat +datum=WGS84"))

# this does the magic for geom_map
world_map <- fortify(world)

# setup the plot
g <- ggplot(d, aes(lon, lat))

# add the map
g <- g + geom_map(data=world_map, map=world_map,
                  aes(x=long, y=lat, map_id=id), 
                  fill="black")

# add your points
g <- g + geom_point(col="red", pch=16)

# set the map limits to the extent of your actual data
# (plus a wee bit more)

g <- g + xlim(extendrange(d$lon, f=1))
g <- g + ylim(extendrange(d$lat, f=0.5))

# approximate mercator without dealing with potential
# issues with coord_map()

g <- g + coord_quickmap()

# quick, nice map theme
g <- g + theme_map()

# show the results
g

根据您的数据在地球上的最终位置,您可能仍然存在一些错误多边形线的问题。如果是这样,请 post 发表评论,我可以更新答案,说明如何使用比当前内置地图数据更少的错误地图数据。

ggplot(dat,aes(x=lon, y=lat))+borders(fill="black",colour="black") +
    geom_point(col="red",pch=16) +
    coord_fixed(xlim = c(100,180),ylim=c(0,40))

事实证明,自 2011 年左右 (!) 以来,ggplot2 中就有这个功能(隐藏得很好)- annotation_map() 函数将地图添加为图层。因此,问题的解决方案将是:

g <- ggplot(d,aes(lon,lat))+
  annotation_map(map_data("world"))+ #Add the map as a base layer before the points
  geom_point(col="red",pch=16)+
 coord_quickmap()  #Sets aspect ratio
plot(g)

coord_quickmap() 函数在这里特别有用,可以将宽高比设置为看起来不错的值。也可以用来扩大地块,使其覆盖整个北海:

g1 <- g+ coord_quickmap(xlim=c(0,15),ylim=c(50,60))
plot(g1)

来自帮助文件:“coord_quickmap() 是一种保留直线的快速近似值。它最适合靠近赤道的较小区域。”有关更多标准投影,请参阅 coord_map() 功能。