【问题标题】:Improve centering county names ggplot & maps改进居中县名ggplot和地图
【发布时间】:2012-03-15 13:17:56
【问题描述】:

我早些时候发布了一个关于使用 ggplot 在地图上绘制县名的问题,并找到了 HERE 的地图。我的第一种方法是采用每个县的所有纬度和经度坐标的方法,如下所示:

谢天谢地,Andrie 有 2 条建议来使用范围中心和 coord_map() {这似乎保持纵横比正确} 来改善居中。这极大地改善了居中,如下所示:

我认为这看起来更好,但在重叠问题上仍有一些困难。我希望进一步改善居中(在同一个线程中,贾斯汀建议使用 kmeans 方法)。如有必要,我可以旋转文本,但我希望名称在必要时居中并旋转(它们超出县界),以便在地图上最好地显示县名。

有什么想法吗?

library(ggplot2); library(maps)

county_df <- map_data('county')  #mappings of counties by state
ny <- subset(county_df, region=="new york")   #subset just for NYS
ny$county <- ny$subregion
p <- ggplot(ny, aes(long, lat, group=group)) +  geom_polygon(colour='black', fill=NA)

#my first approach to centering
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, FUN=mean)
ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=3)

#Andrie's much improved approach to centering
cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                    FUN=function(x)mean(range(x)))
ggplot(ny, aes(long, lat)) +  
    geom_polygon(aes(group=group), colour='black', fill=NA) +
    geom_text(data=cnames, aes(long, lat, label = subregion), size=3) +
    coord_map()

【问题讨论】:

    标签: r ggplot2 geocoding


    【解决方案1】:

    这是一次非常有帮助的讨论。为了那些与dplyr 一起长大的人的利益,这里有一个小调整,使用管道代替aggregate

    library(maps); library(dplyr); library(ggplot2)
    ny <- map_data('county', 'new york') 
    
    cnames1 <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                         FUN=function(x)mean(range(x)))
    cnames2 <- ny %>% group_by(subregion) %>%
        summarize_at(vars(long, lat), ~ mean(range(.)))
    
    all.equal(cnames1, as.data.frame(cnames2))
    

    【讨论】:

      【解决方案2】:

      PAL labeling library 似乎可以自动完成您正在寻找的工作。此屏幕截图取自他们的网站:

      不过,我还没有找到它的 R 接口。 quick guide to perform your own integration of PAL within your favourite GIS application 表明集成本身应该是可行的。但是,在 ggplot2 上下文中,这意味着必须在渲染期间执行标签放置——我不知道这是否可能或如何实现这一点。

      【讨论】:

      • 这看起来很有希望。感谢分享。如果有人要以合理的方式创建和 R 包接口,那么您将拥有一个非常有用的包(尽管这超出了我目前的技能水平)。
      【解决方案3】:

      当我昨晚在 Talk Stats (link) 上解决这个问题时,如果你使用 R 空间包 ( sp)。我测试了他们的一些其他函数来创建一个 SpatialPolygons 对象,您可以在该对象上使用 coordinates 来返回多边形质心。我只为一个县做过,但 Polygon (S4) 对象的 标签点 与质心匹配。假设这是真的,那么 Polygon 对象的标签点就是质心。我使用这个小过程来创建质心数据框并使用它们在地图上绘图。

      library(ggplot2)  # For map_data. It's just a wrapper; should just use maps.
      library(sp)
      library(maps)
      getLabelPoint <- # Returns a county-named list of label points
      function(county) {Polygon(county[c('long', 'lat')])@labpt}
      
      df <- map_data('county', 'new york')                 # NY region county data
      centroids <- by(df, df$subregion, getLabelPoint)     # Returns list
      centroids <- do.call("rbind.data.frame", centroids)  # Convert to Data Frame
      names(centroids) <- c('long', 'lat')                 # Appropriate Header
      
      map('county', 'new york')
      text(centroids$long, centroids$lat, rownames(centroids), offset=0, cex=0.4)
      

      这不适用于每个多边形。 GIS 中的标注和注记过程通常要求您针对那些不适合您要使用的自动(系统)方法的特殊情况调整标注和注记。我们对此采取的code-look-recode方法并不合适。最好包括检查给定图的给定大小的标签是否适合多边形;如果没有,请将其从文本标签记录中删除,然后手动插入以适应情况 - 例如,添加一条引导线并在多边形的一侧进行注释,或者将标签侧向显示,如在其他地方显示的那样。

      【讨论】:

      • 这进一步提高了居中,但正如您所指出的,一些微调将不得不是扭转和转动,拉动和戳(也许不是戳,但是......)。我想这就是我一直在寻找的答案。
      • 有关定位点(ggplot 的定位器功能)的更多信息,请参阅HERE。 David Kahle 的这个函数允许您生成点击点的数据框,以便通过我上面描述的方法轻松操作县标签。
      【解决方案4】:

      我认为这个问题最简单的答案是 Andrie 已经解决了大部分手工作业。其余的需要通过一些好的 ol'adjust 和 see 方法来完成。当你在 Andrie 的建议之后查看情节时,除了一些讨厌的位置,可以通过纬度/经度变化或旋转来改善大部分情况。我有一个 suffolk(右下)和 herkimer(中)的例子,因为 suffolk 的位置可以通过 lat/long 调整和 herkimer 通过旋转来改善。

      之前:

      cnames <- aggregate(cbind(long, lat) ~ subregion, data=ny, 
                          FUN=function(x)mean(range(x))) #Andrie's code
      
      cnames[52, 2:3] <- c(-73, 40.855)  #adjust the long and lat of poorly centered names
      cnames$angle <- rep(0, nrow(cnames)) #create an angle column
      cnames[22, 4] <- -90    #adjust the angle of atypically shaped
      
      ggplot(ny, aes(long, lat)) +  
          geom_polygon(aes(group=group), colour='black', fill=NA) +
          geom_text(data=cnames, aes(long, lat, label = subregion, colour=col, 
          angle=angle), size=3) + coord_map()
      

      这给了我们:

      除非有人有更好的方法,否则我会将这个答案标记为正确。

      【讨论】:

        【解决方案5】:

        您可以查看directlabels 包,它使用许多避免重叠的算法提供自动标签放置。我不确定它是否可以用来解决你的问题,但你可以看看。

        【讨论】:

        • 我为这个问题使用了直接标签,但没有找到应用它的方法。 directlabels 似乎与图例一起使用(作为替代)
        猜你喜欢
        • 2021-11-02
        • 2012-03-15
        • 1970-01-01
        • 1970-01-01
        • 2012-12-06
        • 1970-01-01
        • 2018-02-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多