首页 > 解决方案 > 如何强制 facet_wrap 在右下角绘制最后一个面板并留下白色间隙

问题描述

我想强制 ggplot 在右下角而不是左下角绘制最后一张图。我尝试了几件事(类似的问题hereherehere),但我无法决定面板的顺序和最后一个情节的位置。

这是我设法做的最接近的事情: 在此处输入图像描述

使用此代码:

data_1 <- data_hydro_NA %>%
  filter(Year >= "2000" & Station_river != "Var@Nice[Napo_3_aval]") %>%
  mutate(Plot_f = factor(Station_river, levels = c("Drac@Chabottes", "Durance@Oraison", "Var@Entrevaux", 
                                                   "Mareta@Vipiteno", "Roya@Breil_sur_Roya", "Var@Carros")))
plot_1 <- ggplot(data_1, aes(Date, Qm3s_norm, group = 1)) +
  geom_line(linetype = 1) + 
  facet_wrap(~ Plot_f) + 
  scale_x_date(name = "Years", limits = c(as.Date("2000-01-01"), as.Date("2021-01-01")), breaks = scales::breaks_pretty(n = 6)) +
  scale_y_continuous(name = expression("Daily discharge normalised by mean interannual discharge [m"^3/"s]")) 

data_2 <- data_hydro_NA %>%
  filter(Year >= "2000" & Station_river == "Var@Nice[Napo_3_aval]") %>%
  mutate(Plot_f = factor(Station_river, levels = c("Var@Nice[Napo_3_aval]")))

plot_2 <- ggplot(data_2, aes(Date, Qm3s_norm, group = 1)) +
  geom_line(linetype = 1) + 
  facet_wrap(~ Plot_f) + 
  scale_x_date(name = "Years", limits = c(as.Date("2000-01-01"), as.Date("2021-01-01")), breaks = scales::breaks_pretty(n = 6)) 

pushViewport(viewport(layout = grid.layout(3, 3)))
print(plot_1, vp = viewport(layout.pos.row = 1:2, layout.pos.col = 1:3))
print(plot_2, vp = viewport(layout.pos.row = 3, layout.pos.col = 3))

但是正如您所看到的,最后一个图的大小与其他图的大小不同,并且未对齐(+ 轴标签,但我想这很容易修复)。

事实上,我希望它看起来或多或少像这个,其中 x 和 y 标签在图中是通用的,第 9 个面板的大小与其他面板相同,它应该在右下角: 在此处输入图像描述

这是我的结构数据的一小部分(对不起,我不知道让它更短):

structure(list(Station_code = c("Y6042010", "Y6042010", "Y6042010",  "Y6042010", "Y6042010", "Y6042010", "Y6042010", "Y6042010", "Y6042010",  "Y6042010", "Y6442015", "Y6442015", "Y6442015", "Y6442015", "Y6442015",  "Y6442015", "Y6442015", "Y6442015", "Y6442015", "Y6442015", "Y6442020",  "Y6442020", "Y6442020", "Y6442020", "Y6442020", "Y6442020", "Y6442020",  "Y6442020", "Y6442020", "Y6442020", "W2022030", "W2022030", "W2022030",  "W2022030", "W2022030", "W2022030", "W2022030", "W2022030", "W2022030",  "W2022030", "Y6624010", "Y6624010", "Y6624010", "Y6624010", "Y6624010",  "Y6624010", "Y6624010", "Y6624010", "Y6624010", "Y6624010", "36750PG",  "36750PG", "36750PG", "36750PG", "36750PG", "36750PG", "36750PG",  "36750PG", "36750PG", "36750PG"), Date = structure(c(17532, 17533,  17534, 17535, 17536, 17537, 17538, 17539, 17540, 17541, 17532,  17533, 17534, 17535, 17536, 17537, 17538, 17539, 17540, 17541,  17532, 17533, 17534, 17535, 17536, 17537, 17538, 17539, 17540,  17541, 17532, 17533, 17534, 17535, 17536, 17537, 17538, 17539,  17540, 17541, 17532, 17533, 17534, 17535, 17536, 17537, 17538, 17539, 17540, 17541, 17532, 17533, 17534, 17535, 17536, 17537,  17538, 17539, 17540, 17541), class = "Date"), Qm3s = c(6.69, 
6.03, 6.34, 10.9, 12.6, 10.1, 8.44, 11.2, 29.9, 17.9, 19.3, 17.7, 
17.4, 18.9, 23.9, 21.8, 20.2, 19.6, 114, 70.1, 19.7, 19.1, 18.2, 
22.3, 29.7, 26.5, 23.6, 25.3, 96.7, 54.9, 0.515, 0.521, 0.566, 
1.32, 1.53, 1.27, 1.36, 1.97, 3.44, 2.83, 4.3025, 5.04708333333333, 
4.15875, 4.64916666666667, 6.1025, 4.70083333333333, 4.48333333333333, 
6.8925, 42.3541666666667, 20.1833333333333, 2.10090909090909, 
2.02742424242424, 2.08424242424242, 2.12212121212121, 2.07333333333333, 
2.12151515151515, 2.09, 2.09242424242424, 2.96333333333333, 2.35757575757576 ), Year = c(2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,  2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,  2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,  2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,  2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,  2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L), Month = c(1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Station_river = c("Var@Entrevaux",  "Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux",  "Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux", "Var@Entrevaux",  "Var@Entrevaux", "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]",  "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]",  "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]",  "Var@Nice[Napo_3_aval]", "Var@Nice[Napo_3_aval]", "Var@Carros",  "Var@Carros", "Var@Carros", "Var@Carros", "Var@Carros", "Var@Carros",  "Var@Carros", "Var@Carros", "Var@Carros", "Var@Carros", "Drac@Chabottes",  "Drac@Chabottes", "Drac@Chabottes", "Drac@Chabottes", "Drac@Chabottes",  "Drac@Chabottes", "Drac@Chabottes", "Drac@Chabottes", "Drac@Chabottes",  "Drac@Chabottes", "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya",  "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya",  "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya",  "Roya@Breil_sur_Roya", "Roya@Breil_sur_Roya", "Mareta@Vipiteno",  "Mareta@Vipiteno", "Mareta@Vipiteno", "Mareta@Vipiteno", "Mareta@Vipiteno",  "Mareta@Vipiteno", "Mareta@Vipiteno", "Mareta@Vipiteno", "Mareta@Vipiteno",  "Mareta@Vipiteno")), row.names
= c(NA, -60L), groups = structure(list(
    Station_code = c("36750PG", "W2022030", "Y6042010", "Y6442015", 
    "Y6442020", "Y6624010"), Station_river = c("Mareta@Vipiteno", 
    "Drac@Chabottes", "Var@Entrevaux", "Var@Nice[Napo_3_aval]", 
    "Var@Carros", "Roya@Breil_sur_Roya"), .rows = structure(list(
        51:60, 31:40, 1:10, 11:20, 21:30, 41:50), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -6L), class = c("tbl_df",  "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",  "tbl_df", "tbl", "data.frame"))

标签: rggplot2

解决方案


我不知道用 ggplot2 或扩展包自然地做到这一点。如果有更直接的方法可以做到这一点,我会很高兴听到它。但是,您可以编辑绘图生成的 gtable 以获得所需的结果。为简洁起见(并且因为我无法在没有错误的情况下运行您的代码),我稍微简化了示例,但它可能对您的情节同样有效。该示例还假设固定 x 轴。

首先,我们将绘图转换为 gtable。我们可以用 . 检查行/列号gtable::gtable_show_layout()

library(ggplot2)
library(grid)

df <- data.frame(
  x = 1:7, y = 1:7,
  facet = LETTERS[1:7]
)

g <- ggplot(df, aes(x, y)) +
  geom_point() +
  facet_wrap(~ facet)

gt <- ggplotGrob(g)
gtable::gtable_show_layout(gt)

在上面的布局中,我们需要确定要交换哪些单元格。我们想将第 7 个面板与第 9 个(空)面板交换。因此,我们找到了属于这些面板的单元格。

panel_7 <- which(gt$layout$l %in% 4:5 & gt$layout$t %in% 14:19)
panel_9 <- which(gt$layout$l %in% 12:13 & gt$layout$t %in% 14:19)

然后,我们调整这些单元格中 grobs 的左 ( l) 和右 ( r) 位置,以便交换它们。

gt$layout$l[panel_7] <- gt$layout$l[panel_7] + 8
gt$layout$r[panel_7] <- gt$layout$r[panel_7] + 8
gt$layout$l[panel_9] <- gt$layout$l[panel_9] - 8
gt$layout$r[panel_9] <- gt$layout$r[panel_9] - 8

grid.newpage(); grid.draw(gt)

reprex 包于 2021-04-01 创建(v1.0.0)


推荐阅读