R语言 在ggplot中绘制nb对象?

x9ybnkn6  于 2023-03-15  发布在  其他
关注(0)|答案(2)|浏览(172)

我想绘制英国的轮廓,沿着我从空间点数据框中生成的nb对象。
问题是,UK的大纲需要非常非常长的时间来绘制--它一直使我的RStudio崩溃。例如,这要么需要非常长的时间来加载,要么我的RStudio就停止响应。

library(raster)    
UK_gadm <- getData("GADM", country="GB", level=0)
    plot(UK_gadm)

所以我在solution中使用ggplot 2,通过以下命令,我可以在几分之一秒内获得UK的轮廓:

library(ggplot2)
UK <- map_data(map = "world", region = "UK") # changed map to "world"
    ggplot(data = UK, aes(x = long, y = lat, group = group)) + 
      geom_polygon() +
      coord_map()

现在的问题是,我希望nb对象以UK的轮廓为背景绘制--然而,这似乎只能在for example这样的基R中实现:

plot(orotl.shp, xlim=c(-125, -115), ylim=c(42,47))
plot(orstationc.neighbors.dist, orstationc.loc, add=T, lwd=2, col="blue")

有没有什么方法可以在ggplot中绘制nb对象,或者有没有一种方法可以让R绘制UK的轮廓,而不会使我的计算机与基本R绘图功能崩溃?

b09cbbtk

b09cbbtk1#

经过一整晚的努力,终于找到了一个快速简单的解决方案。希望这对其他有类似问题的人有所帮助。
我们来详细说明一下目标:在一个shapefile中绘制一个邻居对象(nb)。这是为了可视化某些坐标之间的联系。在谷歌上搜索之后,我认为这只能用base R的plot函数来完成。然而,问题是加载一个国家的shapefile(从官方资源/gadm下载)--它太大了。
要解决这个问题,通过maps包得到一个更概括、更简单的国家Map,将其转换为shapefile,然后将其绘制在neighbors对象旁边。
下面是代码:

library(spdep)

# get your neighbour object from your spatial points df
rest_neighbours <- dnearneigh(rest_spdf,0,1)

library(maps)

# get boundary of UK
UK_map <- sf::st_as_sf(maps::map(database='world',regions='UK', plot = FALSE, fill = TRUE))

# write to shapefile
st_write(UK_map, 'shapefiles/UK.shp')

# henceforth, we can just call the shapefile 
UK <- readOGR('shapefiles/UK.shp')

# plot the boundary and the neighbours
plot(UK)
plot(rest_neighbours, rest_coords, add=T, lwd=2, col="blue")

我没有意识到官方的边界文件通常非常详细,这也意味着它们非常庞大,我很高兴在r的Map包中有现成的淡化版本的Map(如果你已经知道了,对不起--我还在学习!)
希望这对其他人有帮助!

enyaitl3

enyaitl32#

library(spdep)
  library(ggplot2)
  library(sf)
  
  # function converts nb object to a data.frame
  # with the coordinates of the lines "x"    "y"    "xend" "yend"
  nb_to_df <- function(nb, coords){
    x <- coords[, 1]
    y <- coords[, 2]
    n <- length(nb)
    cardnb <- card(nb)
    i <- rep(1:n, cardnb)
    j <- unlist(nb)
    return(data.frame(x=x[i], y=y[i], 
                      xend=x[j], yend=y[j]))
  }
  
  # Use this function to support the conversion of the dataframe to sf.  st_sf(st_sfc()) is needed in addition
  st_segment = function(r){sf::st_linestring(t(matrix(unlist(r), 2, 2)))} 
  #as we are not using here byrow=T, we have to use
  #transpose to have the format:
  #x1 y1
  #X2 Y2
  
  #Here one example
  ColData1 <- sf::st_read(system.file("shapes/columbus.shp", package="spData")[1], quiet=TRUE)
  coords1 = sf::st_coordinates(sf::st_centroid(ColData1)) # coordinates of the census tract centroids
  IDs1 = row.names(ColData1)
  ColData1$IDs1 = IDs1
  col_nb1 = poly2nb(ColData1, queen = TRUE)
  summary(col_nb1)
  class(col_nb1) # check the class of col_nb
  #A neighbours list with class nb (output of spdep::poly2nb )
  
  # this is a dataframe with the coordinates of the lines "x"    "y"    "xend" "yend"
  col_nb1_df = nb_to_df(col_nb1, coords1)
  
  col_nb1_df$geom = st_sfc(sapply(1:nrow(col_nb1_df), 
                                  function(i){st_segment(col_nb1_df[i,])}, simplify=FALSE)) 
  # the simplify = FALSE force to return LINESTRING (x1 y1, x2 y2)
  
  #convert to sf
  col_nb1_sf = sf::st_sf(col_nb1_df)
  
  # plot
  ggplot() +
    geom_sf(data=ColData1, fill=NA, color="red", lwd=0.5) +
    geom_sf(data=sf::st_centroid(ColData1), pch=19, color="blue") +
    geom_sf(data=col_nb1_sf, color="blue", lwd=0.3, lty=2) +
    geom_sf_label(data=ColData1, aes(label=IDs1), size = 2) +
    #geom_sf_text(data=ColData1, aes(label=IDs1), size = 3) +
    labs(title="Adjacency Connection", subtitle = "Columbus Shapefile") + 
    xlab("") +
    ylab("")

相关问题