去掉 facet_grid 第一行的空白面板
get rid of empty panels in the first row of facet_grid
我尝试使用 facet_grid
来布置面板,例如,
library(tidyverse)
library(lubridate)
economics %>%
filter(date >= ymd(19680101)) %>%
mutate(
year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")
) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
我的问题是,我怎样才能使用前 7 个面板(和后 4 个),让它们完全空白?
我发现这最容易通过在绘图前编辑 gtable
中的面板 grobs 来完成。
首先让我们将 ggplot 对象保存在 myplot
myplot <- economics %>%
filter(date >= ymd(19680101)) %>%
mutate(
year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")
) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
现在我们可以在绘图前移除面板。我演示了如何使用 cowplot::plot_to_gtable
,尽管还有其他几个提供将 ggplot 转换为 gtable 的函数的包。
library(cowplot)
library(grid)
gt <- plot_to_gtable(myplot)
to.delete = which (gt$layout$t == 8 & gt$layout$r <= 19 & grepl('panel', gt$layout$name))
to.delete = c(to.delete, which(gt$layout$t == 18 & gt$layout$r >= 17 & grepl('panel', gt$layout$name)))
gt$grobs[to.delete] <- NULL
gt$layout <- gt$layout[-to.delete, ]
grid.newpage()
grid.draw(gt)
我们也可以像这样向上移动空单元格的轴:
to.move = which(gt$layout$r >= 17 & grepl('axis-b', gt$layout$name))
gt$layout$t[to.move] <- gt$layout$t[to.move] - 2
gt$layout$b[to.move] <- gt$layout$b[to.move] - 2
grid.newpage()
grid.draw(gt)
对于 ggplot2
的当前开发版本(见下文 *),gtable
中的面板名称 grobs
更正为 'panel-[row]-[col]'
。
这允许使用 gtable_filter()
以直接的方式通过名称(例如 'panel-6-8'
)手动删除某些面板:
# remotes::install_github("tidyverse/ggplot2")
library(ggplot2)
library(dplyr)
library(lubridate)
myplot <- economics %>%
filter(date >= ymd(19680101)) %>%
mutate(year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
myplot %>%
# Generate gtable of ggplot object
ggplot2::ggplot_build() %>% ggplot2::ggplot_gtable() %>%
# Modify gtable by filtering out grobs based on name using a regex pattern
# $ represents end of string. Otherwise 'panel-1-1' removes 'panel-1-10', too.
gtable::gtable_filter(pattern = "panel-1-1$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-2$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-3$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-4$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-5$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-6$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-7$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-8$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-7$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-8$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-9$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-10$", invert = TRUE) %>%
# Plot the modified gtable
{grid::grid.newpage(); grid::grid.draw(.)}
由 reprex package (v0.3.0)
于 2020-05-01 创建
为了识别面板名称,我使用了以下代码片段:
# Plot panel-names
# Extract panels from the gtable layout (incl. their names and positions)
gtable_panel_positions <- myplot %>%
ggplotGrob() %>%
magrittr::extract2("layout") %>%
filter(grepl("panel-",name))
# Generate grobs with labels
grobs_to_add <-
sprintf("name: '%s'\ngtable index: [%d,%d]",
gtable_panel_positions$name,
gtable_panel_positions$t,
gtable_panel_positions$l) %>%
lapply(grid::textGrob, gp=grid::gpar(fontsize=5))
# Add grobs with labels and plot
myplot %>%
ggplotGrob() %>%
gtable::gtable_add_grob(grobs = grobs_to_add,
t=gtable_panel_positions$t,
l=gtable_panel_positions$l) %>%
{grid::grid.newpage(); grid::grid.draw(.)}
由 reprex package (v0.3.0)
于 2020-05-01 创建
您可以通过remotes::install_github("tidyverse/ggplot2")
.
获取ggplot2
*的最新开发版本
* ggplot2 版本截至 2020-05-01,提交:#e0f1040c1217585b22111b2ed11cd967320dcccd
我尝试使用 facet_grid
来布置面板,例如,
library(tidyverse)
library(lubridate)
economics %>%
filter(date >= ymd(19680101)) %>%
mutate(
year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")
) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
我的问题是,我怎样才能使用前 7 个面板(和后 4 个),让它们完全空白?
我发现这最容易通过在绘图前编辑 gtable
中的面板 grobs 来完成。
首先让我们将 ggplot 对象保存在 myplot
myplot <- economics %>%
filter(date >= ymd(19680101)) %>%
mutate(
year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")
) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
现在我们可以在绘图前移除面板。我演示了如何使用 cowplot::plot_to_gtable
,尽管还有其他几个提供将 ggplot 转换为 gtable 的函数的包。
library(cowplot)
library(grid)
gt <- plot_to_gtable(myplot)
to.delete = which (gt$layout$t == 8 & gt$layout$r <= 19 & grepl('panel', gt$layout$name))
to.delete = c(to.delete, which(gt$layout$t == 18 & gt$layout$r >= 17 & grepl('panel', gt$layout$name)))
gt$grobs[to.delete] <- NULL
gt$layout <- gt$layout[-to.delete, ]
grid.newpage()
grid.draw(gt)
我们也可以像这样向上移动空单元格的轴:
to.move = which(gt$layout$r >= 17 & grepl('axis-b', gt$layout$name))
gt$layout$t[to.move] <- gt$layout$t[to.move] - 2
gt$layout$b[to.move] <- gt$layout$b[to.move] - 2
grid.newpage()
grid.draw(gt)
对于 ggplot2
的当前开发版本(见下文 *),gtable
中的面板名称 grobs
更正为 'panel-[row]-[col]'
。
这允许使用 gtable_filter()
以直接的方式通过名称(例如 'panel-6-8'
)手动删除某些面板:
# remotes::install_github("tidyverse/ggplot2")
library(ggplot2)
library(dplyr)
library(lubridate)
myplot <- economics %>%
filter(date >= ymd(19680101)) %>%
mutate(year = year(date),
month = month(date),
decade = floor(year/10) * 10,
single = year - decade,
decade = paste0(decade, "s")) %>%
ggplot(aes(month, uempmed)) +
geom_point() +
facet_grid(decade ~ single)
myplot %>%
# Generate gtable of ggplot object
ggplot2::ggplot_build() %>% ggplot2::ggplot_gtable() %>%
# Modify gtable by filtering out grobs based on name using a regex pattern
# $ represents end of string. Otherwise 'panel-1-1' removes 'panel-1-10', too.
gtable::gtable_filter(pattern = "panel-1-1$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-2$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-3$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-4$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-5$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-6$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-7$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-1-8$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-7$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-8$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-9$", invert = TRUE) %>%
gtable::gtable_filter(pattern = "panel-6-10$", invert = TRUE) %>%
# Plot the modified gtable
{grid::grid.newpage(); grid::grid.draw(.)}
由 reprex package (v0.3.0)
于 2020-05-01 创建为了识别面板名称,我使用了以下代码片段:
# Plot panel-names
# Extract panels from the gtable layout (incl. their names and positions)
gtable_panel_positions <- myplot %>%
ggplotGrob() %>%
magrittr::extract2("layout") %>%
filter(grepl("panel-",name))
# Generate grobs with labels
grobs_to_add <-
sprintf("name: '%s'\ngtable index: [%d,%d]",
gtable_panel_positions$name,
gtable_panel_positions$t,
gtable_panel_positions$l) %>%
lapply(grid::textGrob, gp=grid::gpar(fontsize=5))
# Add grobs with labels and plot
myplot %>%
ggplotGrob() %>%
gtable::gtable_add_grob(grobs = grobs_to_add,
t=gtable_panel_positions$t,
l=gtable_panel_positions$l) %>%
{grid::grid.newpage(); grid::grid.draw(.)}
由 reprex package (v0.3.0)
于 2020-05-01 创建您可以通过remotes::install_github("tidyverse/ggplot2")
.
ggplot2
*的最新开发版本
* ggplot2 版本截至 2020-05-01,提交:#e0f1040c1217585b22111b2ed11cd967320dcccd