magick
magick copied to clipboard
`image_graph` device is very slow (with benchmarking code and alternative with `png` device)
trafficstars
I found that making plot withimage_graph device is very slow. Making plots in temporary files with png (or jpeg) and reading these files with image_read is x15 faster!
Figure Elapsed time to draw n plots.
| n | png | image_draw |
|---|---|---|
| 1 | 0.03 | 0.24 |
| 10 | 0.16 | 2.40 |
| 20 | 0.30 | 4.76 |
Table Elapsed time (sec).
Benchmaking:
# make plots with png device in temporarz files and read them
mk_plot_png <- function(n, tempdir="./tmp") {
# R base device
png(filename = paste(tempdir,"graph_%04d.png",sep="/"),
width = 960, height = 480, res = 72)
# make plots
for(i in 1:n) plot(1:10, (1:10)/i)
dev.off()
# read graphs
fn <- sprintf("%s/graph_%04d.png" , tempdir, 1:n)
graphs <- magick::image_read(fn)
# remove files
#unlink(fn)
graphs
}
# make plots with image_draw device
mk_plot_image_draw <- function(n) {
# open magick graphical device (VERY SLOW)
graphs <- magick::image_graph(width = 960, height = 480, res = 72)
# create an image for each time
for(i in 1:n) plot(1:10, (1:10)/i)
dev.off()
graphs
}
# both function generate n png images
mk_plot_image_draw(n=2)
format width height colorspace matte filesize density
1 PNG 960 480 sRGB TRUE 0 72x72
2 PNG 960 480 sRGB TRUE 0 72x72
mk_plot_png(n=2, tempdir = "./tmp/")
format width height colorspace matte filesize density
1 PNG 960 480 sRGB FALSE 2643 28x28
2 PNG 960 480 sRGB FALSE 2619 28x28
Note that density for png is in pixels/cm (28 pixed/cm = 72 dpi) because the PNG format does not support DPI (see http://www.w3.org/TR/2003/REC-PNG-20031110/#11pHYs). In principle, it should be possible to redefine the units when displaying the info
convert r.png -units pixelsperinch -verbose info:
to get the same output but coud not find how to do it with R magick.
# data frame to store timing results
res <- expand.grid(
device = c("png","image_draw"),
n = c(1, 10, 20),
elapsed = NA)
for(i in 1:nrow(res)) {
n <- res$n[i] # number of plots to draw
if(res$device[i]=="png") {
res$elapsed[i] <- system.time(
graphs <- mk_plot_png(n, tempdir = "./tmp/"))["elapsed"]
} else {
res$elapsed[i] <- system.time(
graphs <- mk_plot_image_draw(n))["elapsed"]
}
image_destroy(graphs)
}
# plot (see above)
lattice::xyplot(elapsed ~ n, group=device, data=res,
type="b", auto.key=TRUE)
Info:
- R version 4.4.2
- magick_2.8.6
`