18

Is it possible to explicitly set the panel size (i.e., the gray grid panel) in a ggplot? I imagine (but can't find) that there is some ggplot extension that allows for arguments that resemble panel.width = unit(3, "in"), panel.height = unit(4, "in").

I have seen solutions for setting the size of the entire plot, or of getting multiple plots to align using the egg package. But nothing that would let me explicitly set the size of the panel.

library(dplyr)
library(ggplot2)
library(tibble)

ds_mt <- mtcars %>% rownames_to_column("model")
mt_short <- ds_mt %>% arrange(nchar(model)) %>% slice(1:4)
mt_long <- ds_mt %>% arrange(-nchar(model)) %>% slice(1:4)

p_short <- 
    mt_short %>% 
    ggplot(aes(x = model, y = mpg)) + 
    geom_col() + 
    coord_flip()

p_short

enter image description here

Joe
  • 3,217
  • 3
  • 21
  • 37
  • Are you looking for `ggsave`? – jan-glx Nov 13 '18 at 16:41
  • @jan-glx, ggsave() can set the dimensions of the entire plot, but I am trying to control the dimensions of the panel within the plot. – Joe Nov 13 '18 at 16:41
  • And by `panel` you mean the area that is usually grey? – jan-glx Nov 13 '18 at 16:50
  • @jan-glx yes, and thank you for clarifying, I have updated the question to reflect this. – Joe Nov 13 '18 at 17:10
  • 1
    I knew that if someone would have [the answer](https://stackoverflow.com/a/32583612/1870254) it would be @baptiste. – jan-glx Nov 13 '18 at 17:31
  • Can you provide a visual of desired result? This may involve using image software (Paint, Paintbrush, Pinta, etc.) – Parfait Nov 13 '18 at 18:20
  • Following @jan-glx link I found that I can use p1 <- set_panel_size(p_short, width = unit(4, "cm"), height = unit(4, "cm")) in combo with grid.arrange(p1) to set panel size explicitly. – Joe Nov 13 '18 at 18:26

2 Answers2

17

The ggh4x package has a similar function to the egg solution presented in the other answer. A slight convenience is that the plot is still a valid ggplot after using the function, so it would work with ggsave() and other layers can be added afterwards. (disclaimer: I wrote ggh4x)

library(dplyr)
library(ggplot2)
library(tibble)
library(ggh4x)

ds_mt <- mtcars %>% rownames_to_column("model")
mt_short <- ds_mt %>% arrange(nchar(model)) %>% slice(1:4)
mt_long <- ds_mt %>% arrange(-nchar(model)) %>% slice(1:4)

mt_short %>% 
  ggplot(aes(x = model, y = mpg)) + 
  geom_col() + 
  coord_flip() +
  force_panelsizes(rows = unit(4, "in"),
                   cols = unit(3, "in"))

Created on 2021-04-21 by the reprex package (v1.0.0)

teunbrand
  • 33,645
  • 4
  • 37
  • 63
13

You can use set_panel_size() function from the egg package

library(tibble)
library(dplyr)
library(ggplot2)

ds_mt <- mtcars %>% rownames_to_column("model")
mt_short <- ds_mt %>% arrange(nchar(model)) %>% slice(1:4)
mt_long <- ds_mt %>% arrange(-nchar(model)) %>% slice(1:4)

p_short <- 
  mt_short %>% 
  ggplot(aes(x = model, y = mpg)) + 
  geom_col() + 
  coord_flip()

library(egg)
library(grid)
p_fixed <- set_panel_size(p_short,
                          width  = unit(10, "cm"),
                          height = unit(4, "in"))
grid.newpage()
grid.draw(p_fixed)

Created on 2018-11-13 by the reprex package (v0.2.1.9000)

Tung
  • 26,371
  • 7
  • 91
  • 115