ggplot:对齐多个刻面图-所有不同大小的刻面

Posted

技术标签:

【中文标题】ggplot:对齐多个刻面图-所有不同大小的刻面【英文标题】:ggplot: align multiple faceted plots - facets all different sizes 【发布时间】:2018-11-10 22:10:02 【问题描述】:

我正在尝试将多个图与构面对齐。我的问题有点小但令人恼火:我可以制作一个绘图,以便绘图区域对齐并且刻面本身对齐,但刻面条的宽度并不完全相同。如果刻面的标签长度​​不同,则刻面条的大小将调整为使文本可以适合刻面。到目前为止,我无法找到一种在对齐多个绘图时使所有刻面条具有相同宽度的方法。

这是我想要对齐的图类型以及我为对齐它们所做的努力的示例:

library(data.table)
library(ggplot2)
library(foreach)
library(stringr)
library(cowplot)

# example data to show how aligning faceted plots is not quite right
plotvars = c(paste0("plot1_var", 1:7), paste0("plot2_var",1:5), paste0("plot3_var",1:10))
data = 
  foreach(p=plotvars,.combine = "rbind") %do% 
    d = data.table(plot = rep(str_extract(p,pattern = "plot[[:digit:]]"),2),
               plot_variables = rep(p,2),
               fill_categories = c("fill1","fill2"),
               number = sample(1:1000, size = 2))
    d[, facet_variables := ifelse(plot=="plot1", 
                                  rep(sample(paste0("facet",1:3),size=1),2),
                                  ifelse(plot=="plot2",
                                         rep(sample(paste0("facet_title",1:3),size=1),2),
                                         ifelse(plot=="plot3",
                                                rep(sample(paste0("facet_title_longer",1:3),size=1),2),
                                                NA)))]
    d
  

# function to make stacked barplots with facets + coord_flip
make_plot = function(data, plot_var) 
  ggplot(data[plot==plot_var],
         aes(x=plot_variables,
             y=number,
             fill=fill_categories))+
    geom_bar(stat="identity")+
    coord_flip()+
    facet_grid(facet_variables ~ ., 
               space="free",
               scales="free")+
    theme(strip.text.y = element_text(angle=0),
          legend.position = "none")

p1 = make_plot(data=data,plot_var="plot1")
p1

p2 = make_plot(data=data,plot_var="plot2")
p2

p3 = make_plot(data=data,plot_var = "plot3")
p3

# using 'cowplot::plot_grid' gives strange re-sizing of individual bars
cowplot::plot_grid(p1,p2,p3, ncol=1,nrow=3,align = "hv")

# try gtable_rbind version
g1=ggplotGrob(p1)
g2=ggplotGrob(p2)
g3=ggplotGrob(p3)

# this plot keeps the bar widths the correct size, but the facets are still incorrectly different widths.
ggdraw(gridExtra::gtable_rbind(g1,g2,g3))

如何使分面条在绘图中具有相同的宽度?

【问题讨论】:

【参考方案1】:

您可以使用标签功能来实现类似的功能,该功能可以插入第二行任意长度的空格。使用mtcars...

#define a function to add a second line of spaces after a given label 
#and a blank line before to maintain the centre vertical alignment
#you might need to play with the appropriate value to get the width right
widen <- function(x) paste(" \n", x, "\n", paste0(rep(" ", 20), collapse=""))

mtcars %>% ggplot(aes(x = mpg)) +
  geom_histogram() +
  facet_grid(cyl ~ ., labeller = labeller(cyl = widen)) +
  coord_flip() +
  theme(strip.text.y = element_text(angle = 0))

【讨论】:

是的,这个解决方案应该可以工作,虽然不是我正在寻找的解决方案——有没有办法用 gtable 和改变条带的宽度来做到这一点?我无法像往常一样弄清楚。如果没有基于修改 grobs 的解决方案,我会将其标记为答案。谢谢! @Tung 我实际上尝试了一种类似于您链接的帖子中的解决方案 - 手动设置 gtable 宽度 - 但它没有改变刻面条的宽度,它只改变了刻面带所在的列。我不明白为什么改变 gtable 宽度实际上并没有改变条带背景颜色区域的宽度。【参考方案2】:

刻面条被包裹在另一个表格中,您需要在那里调整宽度。以下似乎有效。

g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)
g3 <- ggplotGrob(p3)

# g3 has the widest strips, so get the width from there and copy over
# to the other plots
stripwidth <- g3$grobs[[13]]$widths 
g1$grobs[[13]]$widths <- stripwidth
g1$grobs[[14]]$widths <- stripwidth
g1$grobs[[15]]$widths <- stripwidth

g2$grobs[[13]]$widths <- stripwidth
g2$grobs[[14]]$widths <- stripwidth
g2$grobs[[15]]$widths <- stripwidth

ggdraw(gridExtra::gtable_rbind(g1,g2,g3))

【讨论】:

这就是我要找的,谢谢!我是修改 ggplot 组件的新手,所以我没有意识到有时您必须修改 grobs 而不是覆盖的 gtable。【参考方案3】:

改变这部分

facet_grid(facet_variables ~ ., 
           space="free",
           scales="free")+

facet_grid(facet_variables ~ ., 
           space="fixed",    # This is the difference
           scales="free")+

【讨论】:

这不起作用。也许我在这个问题上不清楚,但是当我在单独构建它们之后对齐它们时,我希望多个单独的图上的构面标签区域具有相同的宽度。

以上是关于ggplot:对齐多个刻面图-所有不同大小的刻面的主要内容,如果未能解决你的问题,请参考以下文章

编辑 emmeans 的箭头图的刻面文本

如何使用ggplot2在2x2排列的不同方面添加水平线?

将刻面ggplots(facet_wrap)与R中的cowplot对齐

如何手动调整刻面大小

刻面标签字体大小[重复]

编辑刻面/条带与绘图之间的距离