Řídící
Řídící

Reputation: 291

Sizing a ggplot precisely

I have got two ggplots, of which I want the size of the grey area to be exactly equal.

Now by playing around I can get very close by setting first plot width to 12 and second plot width to 14.

ggsave(filename="test1.png", myPlot, width = 12, height =12, dpi=300, units="cm", device='png')
ggsave(filename="test2.png", myPlot, width = 14, height =12, dpi=300, units="cm", device='png')

enter image description here

My question is whether I can pull some variable(s) from the first plot, so that I can automatically compute the right width for the second plot (ie, the width that makes the grey areas identical in size).

Upvotes: 0

Views: 210

Answers (2)

teunbrand
teunbrand

Reputation: 37903

Aside from the options already given by Allan, you might also find ggh4x::force_panelsizes() convenient to set sizes for plots (disclaimer: I wrote it).

library(ggplot2)

a <- ggplot(mpg, aes(displ, hwy, colour = cyl)) +
  geom_point()

b <- ggplot(iris, aes(Sepal.Width, Sepal.Length, colour = Species)) +
  geom_point() +
  guides(y.sec = "axis")

a + ggh4x::force_panelsizes(rows = unit(4, "cm"), cols = unit(5, "cm"))

b + ggh4x::force_panelsizes(rows = unit(4, "cm"), cols = unit(5, "cm"))

Created on 2022-11-04 by the reprex package (v2.0.0)

Upvotes: 2

Allan Cameron
Allan Cameron

Reputation: 173793

To be absolutely sure about the size of the panel, it is best to build both plots and copy the widths of one plot to the widths of the other.

Let's take two simple plots using built-in data.

library(ggplot2)
library(grid)

p1 <- ggplot(iris, aes(Sepal.Width, Petal.Length, color = Species)) +
  geom_point()

p2 <- ggplot(mtcars, aes(wt, mpg)) + geom_point()

p1

p2

We can see that the width of the gray panel is different in the two plots.

Now we build both of these as a gtable - this is normally done as part of the ggplot print method, but we can halt it at the stage before it actually draws on screen so we have the plots as graphical objects:

p1_built <- ggplot_gtable(ggplot_build(p1))
p2_built <- ggplot_gtable(ggplot_build(p2))

Now we simply copy the widths from first plot over to the second plot:

p2_built$widths <- p1_built$widths

To draw them we can do:

grid.newpage()
grid.draw(p1_built)

grid.newpage()
grid.draw(p2_built)

Note that the panels are now exactly the same size.

An easier method, if you don't mind the plots both being on the same page, is to use patchwork. This is as simple as:

library(patchwork)

p1 / p2

enter image description here

Created on 2022-11-04 with reprex v2.0.2

Upvotes: 2

Related Questions