How to make saving ggplot2 objects more efficient?

I am trying to create weighted density diagrams with R using the ggplot2 package and save them as .png files. In my code, I create 100-1000 of these graphs with different geographical coordinates.

The problem is that if my dataset is 1500 points, then the ggsave function becomes very slow. Then, it takes about 100 seconds to save one of these areas. From what I understand, computational inefficiency comes from the fact that the ggplot2 objects I draw are grids, and ggsave needs to print them before saving them.

So, I ask, is there a way to make saving these ggplot2 objects more efficient? I mean any other way than lowering the resolution of the kde2d density estimate, which will actually make the data graph smaller.

I presented a minimal working example in which I create one of the .png files. When you use system.time () around the ggsave function, you will see that it takes about 100 to execute it.

library(MASS) library(ggplot2) library(grid) x <- runif(1550, 0, 100) y <- runif(1550, 0, 100) wg <- runif(1550, 0, 1) data <- data.frame(x, y, wg) source("C:/Users/cpt2avo/Documents/R/kde2dweighted.r") dens <- kde2d.weighted(data$x, data$y, data$wg) dfdens <- data.frame(expand.grid(x=dens$x, y=dens$y), z=as.vector(dens$z)) p <- ggplot(data, aes(x = x, y = y)) + stat_contour(data = dfdens, geom = "polygon", bins = 20, alpha = 0.2, aes(x = x, y = y, z = z, fill = ..level..)) + scale_fill_continuous(low = "green", high = "red") + scale_alpha(range = c(0,1), limits = c(0.5, 1), na.value = 0) + labs(x = NULL, y = NULL) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(), axis.line = element_blank(), plot.margin = unit(c(0,0,-0.5,-0.5), "line"), panel.border = element_blank(), panel.grid = element_blank(), panel.margin = unit(c(0,0,0,0), "mm"), legend.position = "none", plot.background = element_rect(fill = "transparent", colour = NA), panel.background = element_blank()) system.time(ggsave(p, file = "C:/Users/cpt2avo/Documents/R/example.png", width = 2, height = 2, units = "in", dpi = 128)) 

Kde2d.weighted is a function for calculating 2d kernel density estimates.

 kde2d.weighted <- function (x, y, w, h, n = 25, lims = c(range(x), range(y))) { nx <- length(x) if (length(y) != nx) stop("data vectors must be the same length") if (length(w) != nx & length(w) != 1) stop("weight vectors must be 1 or length of data") gx <- seq(lims[1], lims[2], length = n) # gridpoints x gy <- seq(lims[3], lims[4], length = n) # gridpoints y if (missing(h)) h <- c(bandwidth.nrd(x), bandwidth.nrd(y)); if (missing(w)) w <- numeric(nx)+1; h <- h/4 ax <- outer(gx, x, "-")/h[1] # distance of each point to each grid point in x-direction ay <- outer(gy, y, "-")/h[2] # distance of each point to each grid point in y-direction z <- (matrix(rep(w,n), nrow=n, ncol=nx, byrow=TRUE)*matrix(dnorm(ax), n, nx)) %*% t(matrix(dnorm(ay), n, nx))/(sum(w) * h[1] * h[2]) # z is the density return(list(x = gx, y = gy, z = z)) } 
+6
source share
1 answer

@AntonvSchantz I encountered the same problems as you, I have very similar experiences. Indeed, it exports to high resolution png through ggsave (), which makes this process slow. My solution was to export to pdf by doing something like:

Over plot creation pdf(paste("plots/my_filename", rn , ".pdf", sep = ""), width = 11, height = 8)

Below is your plot creation: dev.off()

+1
source

Source: https://habr.com/ru/post/971902/


All Articles