Consistent plot size for pdf-export in ggplot2

Viewed 788

Similar questions had been asked, but I haven't found the solution to my specific problem.

How can I export my plots in the same dimension? Here's my example:

Scatter plot from mpg dataset with facetting years in plot 1. Plot 2 is the same plot, but with data only from one year (one instead of two facets). I exported the plots as .pdf using ggsave().

library(tidyverse)

p1 <- ggplot(mpg, aes(x = displ, y = cty, color = class))+
  geom_point()+
  facet_wrap(. ~ year) 

p2 <- ggplot(filter(mpg, year == 1999), aes(x = displ, y = cty, color = class))+
  geom_point()+
  facet_wrap(. ~ year) 

ggsave(p1, filename = "p1.pdf")
ggsave(p2, filename = "p2.pdf")

The resulting plots (on standard pdf-export settings, in this case 8.74 x 9.02) look like this:

p1

p2

The individual plots maintain their line-thickness, font-size, etc., but not the size of the plotting area or the individual facets and thus width of the bars do also change.

I understand, that i can adjust the size of the pdf, like this:

ggsave(p1, filename = "p1_manual_size.pdf", width = 16, height = 9.02 )
ggsave(p2, filename = "p2_manual_size.pdf", width = 8.74, height = 9.02)

And this is how they look:

p1_manual_size

p2_manual_size

This works for some instances fairly well, but if plots are becoming more complex (more facets, different positions of legend, etc.), it is getting very complicated (and most of the times impossible) to maintain the plot-area ratios.

So, here's the question: Is it possible to maintain these ratios of a plot in ggplot2, so that the distance - for instance between x-axis elements/ticks - stay the same and the more elements (more values on x-axis) are added the wider the exported plot will become?

It would be great if it would be possible to follow the same logic as for instance GraphPad Prism does, where plots are plotted in the middle of a A4 canvas and they become bigger if there are more let's say columns (and individual columns maintain the same width).

Not sure if I phrased the question well and I hope you will get my point here.

Any help is highly appreciated!

Best, Ben

1 Answers

In the meantime, I figured out a solution myself, that I happily like to share:

I found that the function set_panel_size() of the egg-package allows to fix the size of plot and its respective facets!

library(tidyverse)
library(egg)

p1 <- ggplot(mpg, aes(x = displ, y = cty, color = class))+
  geom_point()+
  facet_wrap(. ~ year) 

p2 <- ggplot(filter(mpg, year == 1999), aes(x = displ, y = cty, color = class))+
  geom_point()+
  facet_wrap(. ~ year) 


p1_fixed <- set_panel_size(p1, width  = unit(3, "cm"),
                               height = unit(5, "cm"))

p2_fixed <- set_panel_size(p2, width  = unit(3, "cm"),
                               height = unit(5, "cm"))

ggsave(p1_fixed, filename = "p1_fixed.pdf", height = 30, width = 21, units = "cm"))
ggsave(p1_fixed, filename = "p1_fixed.pdf", height = 30, width = 21, units = "cm"))

The resulting output looks like this:

p1_fixed:

p1_fixed

p2_fixed:

p2_fixed

The process is not entirely automated, because it still requires to provide a width and height for the plotting panel and won't adjust automatically if more x-axis entries are provided, but it definitely helped to solve my problem.

Related