【问题标题】:Parsimonious way to add north arrow and scale bar to ggmap向ggmap添加指北针和比例尺的简约方法
【发布时间】:2016-08-23 01:20:04
【问题描述】:

我正在尝试使用 ggmap 来创建我正在工作的保护区的地图,并使用来自下方谷歌地球的卫星图像。除了缺少指北针和比例尺之外,我可以制作出非常令人满意的图像:

我知道添加这些元素的方法非常冗长(例如here),但肯定有更简洁的方法来做到这一点!

我尝试过使用map.scalenorth.arrow,但它们都给了我:

Error in polygon(xb + arrow.x * s, yb + arrow.y * s, ...) : 
  plot.new has not been called yet

我可以使用plotmap.scalenorth.arrow 在base R 中工作,但是我无法正确绘制我的卫星图像。我也可以在基本 R 中使用 arrowstext 获得我想要的东西,但这些在 ggmap 中也不起作用。

我正在使用的代码如下。您将没有多边形(因此我不会将其包含在代码中),但您将能够加载谷歌地球图像并复制错误。

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.scalenorth.arrow 函数似乎无法将 ggmap 函数创建的窗口识别为打开的图形窗口。我做了一些研究并试图解决这个问题,但没有任何效果。有没有人能够建议一种方法来解决我收到的错误或在 ggmap 中获得比例尺和指北针而不使用数百行代码?

【问题讨论】:

  • ggsn 软件包不适合您? (cran.rstudio.com/web/packages/ggsn) 另外,如果你真的很在意简洁,“简洁”就是少 3 个字符和 $BIGWORD。
  • 这个对我有用:github.com/3wen/legendMap 我喜欢 ggsn 的外观,但与 legendMap 相比,要让它与 ggmap 一起工作实在是太麻烦了

标签: r ggplot2 ggmap


【解决方案1】:

看起来 map.scalenorth.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"))  

【讨论】:

    【解决方案2】:

    我倾向于使用自己的函数在 ggmap 上绘制比例尺。这为您提供了精确的控制,可以准确地按您想要的方式进行布局。例如,

    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) 
    

    【讨论】:

    • 不错。我将它与米单位投影一起使用。调整以下部分 text = c(as.character(seq(0.0, ((n+1)*d)/1000, by=d/1000)), units) 以在比例尺中显示公里数。
    猜你喜欢
    • 2018-10-24
    • 2016-04-26
    • 1970-01-01
    • 2016-11-28
    • 2016-01-26
    • 2017-08-13
    • 2020-08-31
    • 2013-08-10
    • 2016-06-22
    相关资源
    最近更新 更多