如何减少地理地图的地块和边界之间的space?

How to reduce the space between the plot and the border for geographic maps?

我正在尝试使用 marmap 库绘制美国东北部的测深图。以下代码加载了正确的范围,但是当我绘制地图时,我在边界和地图之间的 top/bottom 或 left/right 处有空白 space 。导出绘图时也会发生这种情况。如果我拖动绘图查看器屏幕大小,绘图会调整,我可以删除几乎所有空的 space 但我将 运行 这个脚本循环,所以用这种方式解决这个问题是不切实际的。由于循环,我也无法将任何维度硬编码到图中,因为它会随着每个新范围而改变。如何设置地块的边界以匹配测深范围?

library(marmap)
library(maps)

atl<- getNOAA.bathy(-80.93645,-41.61417,30.2 ,60.905 ,resolution=4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4),grey(0.99)))

plot(atl, image = TRUE, land = TRUE, n=0,
     bpal = list(c(0, max(atl), greys(100)),
                 c(min(atl), 0, blues(100))))
map(database= "state", col="black", fill=FALSE, add=TRUE)
text(x=state.center$x, y=state.center$y, state.abb, cex=0.5)

此行为是由 plot.bathy()asp 参数引起的。默认固定为asp = 1,保证两个轴的刻度相同(1度经度等于1度纬度)。此默认设置的一个不受欢迎的结果是,白色条带出现在图表的 left/right 侧或 top/bottom 侧,具体取决于测深图和绘图设备的尺寸。

所以我想你有两个选择:

  1. 如果您不介意视角稍微扭曲,可以在调用 plot.bathy()
  2. 时设置 asp = NA
  3. 如果您想获得正确的纵横比但需要为您的绘图区域使用默认大小,那么您必须下载一个覆盖活动设备整个绘图区域的测深区域。例如,您可以调用 plot.bathy() 一次来创建一个 "default" 绘图,然后使用 par("usr") 来确定填充整个绘图区域所需的测深范围。然后,您将下载具有适当经度和纬度范围的第二个测深数据。这可能是不可取的。

这是第二个选项的代码:

atl <- getNOAA.bathy(-80.93645, -41.61417, 30.2, 60.905, resolution = 4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4), grey(0.99)))

plot(atl, image = TRUE, land = TRUE, n = 0,
     bpal = list(c(0, max(atl), greys(100)),
                 c(min(atl), 0, blues(100))))

coord <- par("usr")
atl2 <- getNOAA.bathy(coord[1], coord[2], coord[3], coord[4], res = 4)
plot(atl2, image = TRUE, land = TRUE, lwd = 0.2,
     bpal = list(c(0, max(atl2), greys(100)),
                 c(min(atl2), 0, blues(100))))
map(database = "state", col = "black", fill = FALSE, add = TRUE)
text(x = state.center$x, y = state.center$y, state.abb, cex = 0.5)

我想 Roman Luštrik 提出的解决方案也可行,但它的不便在于让白色条带在图的两边都可见。

顺便说一句,如果你有很多测深区域要绘制,你应该考虑使用 getNOAA.bathy()keep = TRUE 参数来避免每次需要重新查询时查询 NOAA 服务器- 执行你的代码(加载本地数据比远程数据快得多)。您还可以一劳永逸地下载全球 4Go ETOPO1 并使用 subset.bathy() 对每个地块所需的测深进行子集化。

这是一个使用解决方法的建议。这个想法是将 bathy 对象转换为 raster 对象,然后使用 rasterVis 中的 levelplot 绘制绘图,使绘图区域正确适合栅格范围。请注意,使用光栅允许具有定义的像素大小,因此可以使用 marmap::plot 方法似乎没有的正确 width/height 比率。

library(raster)
library(rasterVis)

r <- marmap::as.raster(atl)

state <- map('state', plot = FALSE) 
state <- data.frame(lon = state$x, lat = state$y) 

state.lab <- data.frame(lon = state.center$x, lat = state.center$y, 
                        label = state.abb)

# you can remove the color legend by adding colorkey = FALSE in levelplot() 
levelplot(r, 
          at = c(seq(min(atl), 0, length.out = 100), 
                 seq(0, max(atl), length.out = 100)[-1]),
          col.regions = c(blues(100), greys(100)), 
          margin = FALSE) +
  xyplot(lat ~ lon, state, type = 'l', 
         col = 'black') +
  xyplot(lat ~ lon, data = state.lab,
         panel = function(y, x, ...) {
         ltext(x = x, y = y, labels = state.lab$label, cex = 0.75)
         })