为什么tmap的渲染速度比ggplot2快80倍?[使用gOSplot2 :: geom_sf()在R中绘制shapefile,在macOS上使用XQuartz/X11图形设备]

spo*_*pls 8 r ggplot2 xquartz r-sf

更新/编辑/表示:使用相同的图形设备渲染相同的空间数据需要1秒而tmap不是80秒ggplot2,即使tmap绘图的R对象的大小是80倍.内部和/或实施btw的差异.包和图形设备?

library(ggplot2); library(sf); 
library(tmap); library(tidyverse)
library(here) # project directory

data(World) # sf object from tmap; Provides Africa polygon

# 'd' data pulled from acleddata.com/data, restricted to Aug 18 2017  - Aug 18 2018, Region: N/S/E/W/Middle Africa only
d <- read.csv(here('2017-08-18-2018-08-18-Eastern_Africa-Middle_Africa-Northern_Africa-Southern_Africa-Western_Africa.csv'))
dsf <- st_as_sf(d, coords = c('longitude', 'latitude'), crs = 4326)
Run Code Online (Sandbox Code Playgroud)

使用的数据:1 - 来自tmap包本身的'世界'shapefile数据,和

2 - acleddata.com/data,2017年 8月18日至2018年8月18日期间限制在非洲的ACLED冲突事件(7.8 MB .csv;这些过滤器:)

在此输入图像描述

绘图渲染:

# ggplot2; build plot, assign to object
dev.cur()   # RStudioGD on macOS: quartz
system.time(p <- ggplot(World %>% filter(continent == 'Africa')) + 
  geom_sf() + 
  geom_sf(data = dsf, aes(fill = event_type, 
              color = event_type)) + 
  ggthemes::theme_tufte() + 
  theme(legend.key.size = unit(.1, 'cm'),
        legend.title = element_blank()))
   # user  system elapsed 
   # 0.016   0.001   0.017 

object.size(p)
# 175312 bytes

# render
system.time(print(p))
# user  system elapsed 
# 84.755   0.432  85.418  # Note over 80 seconds
Run Code Online (Sandbox Code Playgroud)

ggplot2 png

# tmap; build plot, assign to object
tmap_mode('plot')
system.time(tm <- tm_shape(World, filter = 
                        (World$continent == 'Africa')) + 
               tm_polygons(group = 'Countries') +
               tm_shape(dsf) + 
               tm_dots(col = 'event_type', group = 'event_type'))
    # user  system elapsed 
    # 0.000   0.000   0.001 

object.size(tm)
# 14331968 bytes   # This is 80x ggplot2 plot's object size
                   # 14331968/175312 = 81.75121
# render
dev.cur()    # RStudioGD on macOS: quartz
system.time(print(tm))
# user  system elapsed 
# 1.438   0.038   1.484   # Note 1 second
Run Code Online (Sandbox Code Playgroud)

tmap png


[之前对geom_sf()和图形设备的查询,没有tmap比较:]

TL; DR:

我试图通过将图形设备切换到X11来加快我的绘图速度,因为我的默认Quartz图形设备很慢.下载XQuartz(连接到X11图形设备)并调用后grDevices::X11(),我不明白我得到的错误.

X11(type = "cairo")
# Error in .External2(C_X11, d$display, d$width, d$height, d$pointsize,  : 
                    #   unable to start device X11
                    # In addition: Warning message:
                    #   In X11() : unable to open connection to X11 display 'cairo'
#> Warning in X11(type = "cairo"): unable to open connection to X11 display ''
Run Code Online (Sandbox Code Playgroud)

当我从macOS上的XQuartz.app终端调用R时,错误消息略有不同:

X11(type = "cairo")
#> Error in .External2(C_X11, d$display, d$width, d$height, d$pointsize, : unable to start device X11cairo
Run Code Online (Sandbox Code Playgroud)

结束TL; DR

~~~~~~~

更广泛的背景:

绘制大型shapefile ggplot2::geom_sf(),macOS绘图中使用的石英图形设备比其他设备慢得多,虽然这个更大的性能问题正在解决,但我想将我的设备从Quartz更改为X11.

我按照RStudio论坛的建议下载了XQuartz,但是我的代码没有成功调用X11,即使我从XQuartz启动了R.

证明,使用与RStudio论坛海报相同的数据:

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3
library(ggplot2)
tmpzip <- tempfile(fileext = ".zip")
download.file("https://github.com/bcgov/bcmaps.rdata/blob/master/data-raw/ecoregions/ecoregions.zip?raw=true", destfile = tmpzip)
gdb_path <- unzip(tmpzip, exdir = tempdir())
ecoregions <- sf::read_sf(dirname(gdb_path[1]))

## Create ggplot2 object
ecoregions_gg <- ggplot() + geom_sf(data = ecoregions)

# Running quartz device - default macOS
system.time(print(ecoregions_gg))
#>    user  system elapsed 
#> 128.980   0.774 130.375

### ^ Note two full minutes!
Run Code Online (Sandbox Code Playgroud)

Shape文件

在给定大小的情况下,此默认设备运行异常长的129秒.根据RStudio论坛,X11应该运行得更快.使用其默认图形设备(非Quartz)对(授予的,更快的)Windows 7计算机(32 GB RAM,3.60 GHz)进行测试,得出:

#>    user  system elapsed 
#>    2.16    2.24    4.46

###  ^Only two seconds
Run Code Online (Sandbox Code Playgroud)

虽然人们正在解决一般的geom_sf/Quartz性能问题(Github问题1,Github问题2),但我如何使用我的XQuartz安装来运行X11并加快我的shapefile绘图?

l--*_*''' 2

关于使用相同的图形设备渲染相同的空间数据,您可能需要考虑以下几件事:

  1. tmap 和 ggplot 使用不同的内部数据结构。tmap 使用 sf 包,该包使用简单特征格式。ggplot2 使用 geom_sf() 函数将空间数据转换为数据框。这可能会导致不同的性能。
  2. tmap 和 ggplot2 有不同的方法来渲染空间数据。tmap 使用专为专题映射而设计的高度优化的渲染引擎。它使用光栅化和地图平铺等技术来高效渲染。ggplot2 是通用的。
  3. 图形设备也会影响渲染性能。

如果您想提高 ggplot2 中 shapefile 绘图的性能,请考虑以下因素:

  1. 使用 sf 包的 st_simplify() 简化 shapefile 的几何。这将减少顶点数量
  2. 限制特征数量