Update/Edit/Reprex: Rendering the same spatial data with the same graphics device takes 1 second with
tmap versus 80 seconds with
ggplot2, even though the
tmap plot's R object is 80x larger in size. Difference in internals and/or implementation btw. packages & graphics device?
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)
Data used: 1 -- 'World' shapefile data from the
tmap package itself, and
2 -- acleddata.com/data, ACLED conflict events restricted to Africa between August 18 2017 and August 18 2018 (7.8 MB .csv; these filters:)
# 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
[Previous inquiry into geom_sf() & graphics devices, without the tmap comparison:]
I am trying to speed up my plotting speed by switching graphics devices to X11, since my default Quartz graphics device is slow. After downloading XQuartz (to connect to the X11 graphics device) and calling
grDevices::X11(), I don't understand the errors I'm getting.
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 ''
And when I call R from a XQuartz.app terminal on macOS instead, the error message is slightly different:
X11(type = "cairo") #> Error in .External2(C_X11, d$display, d$width, d$height, d$pointsize, : unable to start device X11cairo
Plotting large shapefiles with
ggplot2::geom_sf(), the quartz graphics device used in macOS plots considerably slower than other devices, and while this larger performance issue is being resolved, I want to change my device from Quartz to X11.
I downloaded XQuartz, following advice from the RStudio forums, but my code doesn't successfully call X11, even when I launch R from XQuartz.
Proof, using the same data as the RStudio forum poster:
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)) ## 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!
This default device runs for an unusually long 129 seconds given the size. X11 should run faster according to the RStudio forum. A test on a (granted, faster) Windows 7 machine (32 GB RAM, 3.60 GHz) using its default graphics device (not Quartz), yielded:
#> user system elapsed #> 2.16 2.24 4.46 ### ^Only two seconds