rggplot2svgexportpng

How to export plots from R without margins and without manually specifying width and height?


I'm creating several plots in R with differing aspect ratios that are intended for use in Latex later.

I have plots similar to this:

library(ggplot2)
library(sf)

map <- st_sf(geometry = st_sfc(st_point(c(0, 0)), st_point(c(1, 2))))
plt <- ggplot(map) +
  geom_sf(aes(), linewidth = 0.2, alpha = 0.4) +
  theme_void() +
  theme(
    plot.title = element_text(hjust = 0.5),
    plot.margin = margin(0,0,0,0),
    axis.ticks.length = unit(0, "pt"),
    plot.background = element_rect(fill = "yellow")
  ) +
  theme(legend.position = "none")

and tried the following export options:

ggsave(
  "whatever.svg", 
  plot = plt)

png("whatever.png")
plot(plt)
dev.off()

For both options, there are white margins left and right to the plot itself. How can I export plots without manually specifying the width and height and without white margins?

I also tried extracting the plot width and heigth from the plot itself (ChatGPT solution) using

p_built <- ggplot_build(plt)

width <- diff(p_built$panel$ranges[[1]]$x.range)
height <- diff(p_built$panel$ranges[[1]]$y.range)

However, I received NULL as a result and wasn't able to .

I do have a slight preference for vector graphics, but I'm also willing to export to .png. My main issue is that I don't want to manually specify the width and height of the plot as the plots all have different aspect ratios and I want to automate that.

What can I change to receive plots without white space around them?


Solution

  • You can use plotsize() from the plotscale package to figure out the dimensions your plot would have if printed to a graphics device of a given size.

    library(plotscale)
    
    size <- plotsize(plt, 7, 7)
    size
    #> width 3.5 in , height 7 in
    

    Then you can adjust the size of the graphics device to cut out the margins:

    ggsave("plt.png", plt, width = size$width, height = size$height)