如何自定义facet_wrap的网格调整行为

时间:2018-12-26 18:32:17

标签: r ggplot2

我需要编写一个使用ggplot2::facet_wrap()进行绘图的函数。将在不同数据上调用此函数,并在构面中使用不同级别的因子。像这样:

plot_by <- function(data, x, y, by){
  x <- ensym(x)
  y <- ensym(y)
  by <- ensym(by)

  p <- data %>% 
    ggplot() + geom_point(aes(!!x, !!y)) + facet_wrap(vars(!!by))

  print(p)
}

通常,facet_wrap在调整构面数量方面做得很好,但我不喜欢其具有3级变量的行为,因为它会创建3个矩形构面并拉长绘图:

diamonds %>% 
  mutate(cut = fct_lump(cut, 2)) %>% 
  plot_by(carat, price, cut)

enter image description here

我想要实现的是自定义调整,以便它更喜欢正方形图而不是矩形图,并创建一个2x2网格,使一个窗口像5级变量一样为空:

diamonds %>% 
  plot_by(carat, price, cut)

enter image description here

我可能会做类似的事情:

if (n_distinct(data$by) == 3){
  p <- data %>% 
    ggplot() + geom_point(aes(!!x, !!y)) + facet_wrap(vars(!!by, ncol = 2))
}

但是也许有一些更好,更通用的解决方案?

1 个答案:

答案 0 :(得分:2)

我认为平方根长宽比的一个好的出发点是将ncol与刻面数量的平方根成比例。这是一个将您的三方面示例放入两行的实现。

plot_by <- function(data, x, y, by){
  x <- ensym(x)
  y <- ensym(y)
  by <- ensym(by)

  cols_tgt <- 
    data %>%
    pull(!!by) %>%
    n_distinct %>%
    sqrt %>%
    ceiling

  p <- data %>%
    ggplot() + 
      geom_point(aes(!!x, !!y)) + 
      facet_wrap(vars(!!by), ncol = cols_tgt)

  print(p)
}

enter image description here