I am adding a background image in R using ggplot. I am doing this in an iterative process, building up multiple slides with the same background.
I have an input worldmap in tiff format, I read it into a ggmap process and then write it out as a tiff file.
world map with urban areas highlighted
I have two problems which I would like some help with: 1. The saved world map picture is written slightly down and to the right in comparison to the input file. Look closely to see this. 2. The saved file loses resolution.
world_background <-tiff::readTIFF("world_background_in.tiff", native = TRUE)
myplt <- ggplot() +
theme_void() + theme(legend.position="none") +
annotation_custom(rasterGrob(world_background,
width = unit(1,"npc"),
height = unit(1,"npc")),
-Inf, Inf, -Inf, Inf) +
scale_x_continuous(limits = c(-180, 180)) +
scale_y_continuous(limits = c(-79.99688, 79.99825))
tiff("world_packground_out.tiff", width=1024, height=580, res=300, compression = "lzw")
print(myplt)
dev.off()
If you run this on an iterative basis, using the saved file as input for the next iteration, you will see that the world pic slides down and right for each output you produce, and the resolution becomes increasingly grainy.
Any suggestion on to keep the image in exactly the same location? And how do I maintain my resolution?
Note: The uploaded image is saved in png format (I think!). If you run my code with png input, the problem is the same
Not sure what is the issue you're facing, response was too long to post in a comment, hence an answer.
I'm using magick::image_read()
to read the background image. Since I don't know what you're trying to plot, I'm using mtcars
as a sample dataset to check if it works in a loop - both the variable to be plotted and scale_y_continuous
are dependant on the column being plotted which might be similar to your use case.
lapply(c('data.table', 'ggplot2', 'grid', 'png', 'magick'),
library, character.only = T)
img <- image_read('https://i.sstatic.net/IwjyT.png')
dat <- as.data.table(mtcars)
plot_list <- lapply(colnames(dat)[1:5], function(z){
plt <- ggplot(dat, aes_string(x = 'wt', y = z)) +
theme(legend.position = 'none') +
annotation_custom(grob = rasterGrob(image = img,
width = unit(1, 'npc'),
height = unit(1, 'npc')),
xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf) +
geom_point() + geom_line() +
scale_x_continuous(limits = dat[, range(wt)]) +
scale_y_continuous(limits = dat[, range(get(z))])
ggsave(filename = sprintf('%s vs Wt.png', z), plot = plt, device = 'png')
return(plt)
})
I found no issues with the plots - confirmed by saving the plot locally. The only time there was a difference in the image size was when the y-axis had more digits for the tick marks (e.g. when plotting cyl
vs when plotting hp
).
I tested this with theme_void
as well - it only removed the x, y axes and made no difference to the plot itself.