代码之家  ›  专栏  ›  技术社区  ›  89_Simple

为什么spplot在多个面板上花费这么多时间

  •  3
  • 89_Simple  · 技术社区  · 5 年前

    我正在使用spplot绘制多个形状文件。这里有一个数据来构造

    library(raster)
    library(randomcoloR)
    
    my.shp <- getData('GADM', country = 'BRA', level = 2)
    my.shp$ID<- 1:nrow(my.shp)
    

    我的数据由一个变量组成 X 如图所示,每列为一年

    df <- matrix(sample(100:5000, 55040, replace = T), nrow = 5504, ncol = 10)
    df <- data.frame(ID = 1:nrow(my.shp), df)
    
    my.dat <- merge(my.shp, df, by = "ID")
    
    variable.names <- paste0("X",1:10)
    
    spplot(my.dat, rev(variable.names), col = NA, at = seq(from = 100, to = 5000, by = 500), 
              col.regions = distinctColorPalette(length(seq(from = 100, to = 5000, by = 500))),
              main = list(label = "TEST")) 
    

    我的问题是,这个图需要花很多时间(大约一个小时)来绘制,并且想知道代码本身是否存在一些固有的错误,以至于需要太长的时间来绘制。我的笔记本电脑有32 GB的内存。

    谢谢

    2 回复  |  直到 5 年前
        1
  •  1
  •   SeGa    5 年前

    你愿意/能够转换到 sf 而不是 sp ?

    sf plot函数比spplot快得多,尽管布局有点不同。

    library(sf)
    my.dat_sf <- st_as_sf(my.dat)
    plot(my.dat_sf[rev(variable.names)], max.plot=10, breaks=c(seq(from = 100, to = 5000, by = 500),5000),
         pal = distinctColorPalette(length(seq(from = 100, to = 5000, by = 500))),
         main = "TEST", border=NA, key.pos=4)
    

    此外,可以尝试使用 rmapshaper::ms_simplify() 对于空间*-对象或 sf::st_simplify() 对于simplefeatures,它允许您根据给定的 dTolerance . 因此,使用简化的多边形绘制也会更快。

    原始空间多边形:

    format(object.size(my.dat_sf), units="Kb")
    

    “25599.2 KB”

    以及简化的简单功能:

    dat_sf_simple <- st_transform(my.dat_sf, crs = 3035)
    dat_sf_simple <- st_simplify(dat_sf_simple, dTolerance = 1000, preserveTopology = T)
    dat_sf_simple <- st_transform(dat_sf_simple, crs = 4326)
    format(object.size(dat_sf_simple), units="Kb")
    

    “7864.2 Kb”

    绘制简化的simplefeature,它在我的8GB RAM机器上大约需要1分钟。

    plot(dat_sf_simple[rev(variable.names)], max.plot=10, breaks=c(seq(from = 100, to = 5000, by = 500),5000),
         pal = distinctColorPalette(length(seq(from = 100, to = 5000, by = 500))),
         main = "TEST", border=NA, key.pos=4)
    

    你也可以试试 ggplot2 但是我很确定最有效的解决方案是SF图。

    library(ggplot2)
    library(dplyr)
    library(tidyr)
    
    dat_sf_simple_gg <- dat_sf_simple %>% 
      dplyr::select(rev(variable.names), geometry) %>% 
      gather(VAR, SID, -geometry)
    
    ggplot() +
      geom_sf(data = dat_sf_simple_gg, aes(fill=SID)) + 
      facet_wrap(~VAR, ncol = 2) 
    
        2
  •  2
  •   SymbolixAU Adam Erickson    5 年前

    我还没有把这个情节和你的相比 spplot 因为我不想花一个小时等它。

    相反,我建议使用 library(mapdeck) 绘制一张交互式地图,需要几秒钟时间。

    需要注意的两件事

    1. 你需要一个mapbox访问令牌
    2. 你需要转换 sp 对象到 sf
    library(raster)
    
    my.shp <- getData('GADM', country = 'BRA', level = 2)
    my.shp$ID <- 1:nrow(my.shp)
    
    df <- matrix(sample(100:5000, 55040, replace = T), nrow = 5504, ncol = 10)
    df <- data.frame(ID = 1:nrow(my.shp), df)
    
    my.dat <- merge(my.shp, df, by = "ID")
    
    
    library(sf)
    sf <- sf::st_as_sf( my.dat )
    
    library(mapdeck)
    
    set_token( "YOUR_MAPBOX_TOKEN" )
    
    mapdeck() %>% 
      add_sf(
        data = sf
        , fill_colour = "GID_2"
        )
    

    enter image description here