Почему tmap рендерит в 80 раз быстрее, чем ggplot2? [Построение шейп-файлов в R с помощью ggplot2::geom_sf() с использованием графического устройства XQuartz/X11 в macOS]
Обновление / Редактирование / Представление: рендеринг одинаковых пространственных данных на одном графическом устройстве занимает 1 секунду с tmap
против 80 секунд с ggplot2
хотя tmap
R-объект участка в 80 раз больше по размеру. Разница во внутренних и / или реализации между прочим. пакеты и графическое устройство?
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)
Используемые данные: 1 - данные шейп-файла "World" из tmap
сам пакет, и
2 - http://acleddata.com/data, конфликтные события ACLED, разрешенные для Африки в период с 18 августа 2017 года по 18 августа 2018 года (7,8 МБ.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
# 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
[Предыдущий запрос в 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 ''
И когда вместо этого я вызываю R из терминала XQuartz.app в macOS, сообщение об ошибке немного отличается:
X11(type = "cairo")
#> Error in .External2(C_X11, d$display, d$width, d$height, d$pointsize, : unable to start device X11cairo
Конец TL; DR
~~~~~~~
Более широкий контекст:
Создание больших шейп-файлов с ggplot2::geom_sf()
кварцевое графическое устройство, используемое в macOS, работает значительно медленнее, чем другие устройства, и хотя эта большая проблема с производительностью решается, я хочу сменить свое устройство с Quartz на X11.
Я скачал XQuartz, следуя советам форумов RStudio, но мой код не вызывает X11, даже когда я запускаю R из XQuartz.
Доказательство, используя те же данные, что и на постере форума 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!
Это устройство по умолчанию работает в течение необычно длинных 129 секунд, учитывая размер. X11 должен работать быстрее в соответствии с форумом RStudio. Тест на (предоставленном, более быстром) компьютере с Windows 7 (32 ГБ ОЗУ, 3,60 ГГц) с использованием графического устройства по умолчанию (не Quartz) дал:
#> user system elapsed
#> 2.16 2.24 4.46
### ^Only two seconds
В то время как люди занимаются устранением общих проблем с производительностью geom_sf / Quartz ( Github Issue 1, Github Issue 2), как я могу использовать мою установку XQuartz для запуска X11 и ускорения прорисовки шейп-файлов?
1 ответ
несколько вещей, которые вы можете рассмотреть при рендеринге одних и тех же пространственных данных на одном и том же графическом устройстве:
- tmap и ggplot используют разные внутренние структуры данных. tmap использует пакет sf, который использует формат простых функций. ggplot2 использует функцию geom_sf(), которая преобразует пространственные данные в фрейм данных. это может привести к различной производительности.
- tmap и ggplot2 имеют разные подходы к рендерингу пространственных данных. tmap использует высокооптимизированный механизм рендеринга, предназначенный для тематического картографирования. для эффективной визуализации он использует такие методы, как растеризация и мозаика карты. ggplot2 предназначен для общего назначения.
- графическое устройство также может влиять на производительность рендеринга.
Если вы хотите улучшить производительность построения шейп-файлов в ggplot2, рассмотрите следующее:
- упростите геометрию шейп-файла, используя st_simplify() пакета sf. это уменьшит количество вершин
- ограничить количество функций