在 ggplot2 的 facet-grid/facet_wrap 中调整面板的相对空间

Posted

技术标签:

【中文标题】在 ggplot2 的 facet-grid/facet_wrap 中调整面板的相对空间【英文标题】:Adjusting the relative space of panels in a facet-grid/facet_wrap in ggplot2 【发布时间】:2016-06-14 14:51:06 【问题描述】:

有没有办法改变facet_gridfacet_wrap 中各个刻面的y 轴高度/长度?

例如,

library(ggplot2)
ggplot(economics_long[economics_long$variable %in% c("pop", "uempmed"),], aes(date, value)) +
    geom_line() +
    facet_grid(variable~., scales = "free_y") +
    theme(strip.background = element_blank())

在上图中,我希望 pop 时间序列 y 轴高度/长度是 uempmed y 轴长度 (2:1) 的两倍,而不管两个时间序列的事实如何有不同的 y 轴刻度。

就像 Kohske 在这里所做的那样,在更旧版本的 ggplot2 中,它在 ggplot >=2.0.0 中不起作用:

https://kohske.wordpress.com/2010/12/25/adjusting-the-relative-space-of-a-facet-grid/

我知道我可以在facet_grid 中指定参数space = "free",但我认为该参数不能用于设置 2:1 的 y 轴比例?

我也不想使用“grid.arrange 类型”解决方案来排列单独创建的 ggplots(我可以在其中制作 2 个具有不同 y 轴长度的单独图),因为理想情况下我想使用在这个单一的facet_wrap 情节中,Shiny 的交互式 ggplot2 功能(例如,带有画笔的交互式闪亮面示例在页面的中间:http://shiny.rstudio.com/articles/selecting-rows-of-data.html)。

【问题讨论】:

您找到解决问题的方法了吗?我在问,因为我有完全相同的问题。当您有 3 个网格并且您希望它们按比例 (2, 1, 1) 时该怎么办。使用 grid_extra 和 heights 参数很容易做到,但它们不能很好地垂直对齐 不幸的是还没有。也许有办法,特别是在过去一年左右对 ggplot2 的更新,但我不知道。我的猜测是它可能仍然需要在我完全不熟悉的 ggplot2 源代码中实现。 【参考方案1】:

有多种选择。

使用facets,您可以使用facet_grid(..., space='free_y') 将每行的高度调整为y 轴的长度。但是,在您的数据集中,底行被最小化为一行(0-25 与 200,000 - 320,000)。

当 ggplot2 对象被绘制/打印时,它们首先被转换为gtable 对象。将您的绘图保存为p,我们可以调用ggplotGrob 来获取gtable 对象。这是一种单向程序;一旦转换,您将无法将 gtable 转换回 ggplot2 对象!

(g <- ggplotGrob(p))
TableGrob (12 x 8) "layout": 18 grobs
    z         cells       name                                    grob
1   0 ( 1-12, 1- 8) background        rect[plot.background..rect.3766]
2   1 ( 6- 6, 4- 4)  panel-1-1               gTree[panel-1.gTree.3696]
3   1 ( 8- 8, 4- 4)  panel-1-2               gTree[panel-2.gTree.3711]
4   3 ( 5- 5, 4- 4)   axis-t-1                          zeroGrob[NULL]
5   3 ( 9- 9, 4- 4)   axis-b-1    absoluteGrob[GRID.absoluteGrob.3725]
6   3 ( 6- 6, 3- 3)   axis-l-1    absoluteGrob[GRID.absoluteGrob.3733]
7   3 ( 8- 8, 3- 3)   axis-l-2    absoluteGrob[GRID.absoluteGrob.3741]
8   3 ( 6- 6, 6- 6)   axis-r-1                          zeroGrob[NULL]
9   3 ( 8- 8, 6- 6)   axis-r-2                          zeroGrob[NULL]
10  2 ( 6- 6, 5- 5)  strip-r-1                           gtable[strip]
11  2 ( 8- 8, 5- 5)  strip-r-2                           gtable[strip]
12  4 ( 4- 4, 4- 4)     xlab-t                          zeroGrob[NULL]
13  5 (10-10, 4- 4)     xlab-b titleGrob[axis.title.x..titleGrob.3714]
14  6 ( 6- 8, 2- 2)     ylab-l titleGrob[axis.title.y..titleGrob.3717]
15  7 ( 6- 8, 7- 7)     ylab-r                          zeroGrob[NULL]
16  8 ( 3- 3, 4- 4)   subtitle  zeroGrob[plot.subtitle..zeroGrob.3763]
17  9 ( 2- 2, 4- 4)      title     zeroGrob[plot.title..zeroGrob.3762]
18 10 (11-11, 4- 4)    caption   zeroGrob[plot.caption..zeroGrob.3764]

所有元素都设置在类似网格的布局中。布局中每一行的高度由g$heights给出:

> g$heights
 [1] 5pt                 0cm                 0cm                 0cm                 0cm                 1null               5pt                 1null               0.396281911581569cm 1grobheight        
[11] 0cm                 5pt    

将'panel-1-1'和'panel-1-2'的坐标匹配到这些高度,你会发现第6个和第8个元素都是1null。您可以将它们更改为任何单位,cm,in,pt,... 1null 只是在其他元素之后留下的,并在它们之间进行划分。所以我们可以把第6个高度改成2null(注意使用双括号):

> g$heights[[6]] <- unit(2, 'null')
> grid.draw(g)

【讨论】:

谢谢,我知道这种制作 ggplots 的方法(我在问题中提到了grid.arrange 类型的解决方案)。但我不认为这实际上回答了我的具体问题......我希望最终能够调整 facet_wrap 中的 y 轴,所以我可以在 Shiny 中使用交互式 ggplot2 图表......请参阅刷点示例我在问题中的 rstudio 链接中的facet_wrap。我不知道这样的事情甚至可以使用grobs 目前还不清楚brushedPoints 是如何工作的;我的猜测是它不能识别绘图上的各个点,而是推断所覆盖的 x 和 y 坐标,并从给定的 data.frame 返回该区域内的任何点。请注意,该函数不会从 ggplot 对象中读取 data.frame,而是必须明确给出;此外,您必须指定正在使用哪些方面。如果您尝试以您尝试的方式将这两个功能结合起来,您将有很多工作要做;尝试使用两个单独的输出绘图小工具。

以上是关于在 ggplot2 的 facet-grid/facet_wrap 中调整面板的相对空间的主要内容,如果未能解决你的问题,请参考以下文章

ggplot2 配色

R语言ggplot2可视化在ggplot2生成的可视化结果下方显示文本:显示一些关于数据的信息

R语言ggplot2可视化:使用R原生plot函数为指定曲线下面的区域着色ggplot2可视化在曲线的特定下方添加分割线ggplot2为指定曲线下面的区域着色

在ggplot2中绘制形状文件

R语言ggplot2可视化:ggplot2可视化密度图(显示数据密集区域)ggplot2可视化密度图(对数坐标):log10比例的收入密度图突出了在常规密度图中很难看到的收入分布细节

在ggplot2中更改条形图轮廓