【问题标题】:Remove unused facet combinations in 2-way facet_grid删除 2-way facet_grid 中未使用的构面组合
【发布时间】:2018-03-27 20:26:16
【问题描述】:

我有两个因子和两个连续变量,我使用它来使用 ggplot2 创建一个双向刻面图。然而,并不是我所有的因子组合都有数据,所以我最终得到了虚拟方面。这是一些产生等效输出的虚拟代码:

library(ggplot2)
dummy<-data.frame(x=rnorm(60),y=rnorm(60),
                  col=rep(c("A","B","C","B","C","C"),each=10),
                  row=rep(c("a","a","a","b","b","c"),each=10))
ggplot(data=dummy,aes(x=x,y=y))+
       geom_point()+
       facet_grid(row~col)

这会产生this figure

有什么方法可以删除不绘制任何数据的构面?并且,理想情况下,将 x 和 y 轴标签向上或向右移动到其余图?如图this GIMPed version

我在这里和其他地方搜索过,除非我的搜索词不够好,否则我在任何地方都找不到相同的问题。类似的问题通常与未使用的因子水平有关,但这里没有未使用的因子水平,只有因子水平组合。所以facet_grid(drop=TRUE)ggplot(data=droplevel(dummy)) 在这里没有帮助。将这些因素组合成一个因素并丢弃新因素的未使用水平只能产生一个一维分面网格,这不是我想要的。

注意:我的实际数据有第三个因素水平,我用不同的点颜色表示。因此,允许我保留图例的单图解决方案将是理想的。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    手动重新排列图形对象 (grobs) 以实现您的目标并不难。

    1. 加载必要的库。

      library(grid);
      library(gtable);
      
    2. 将您的ggplot2 绘图转换为grob

      gg <- ggplot(data = dummy, aes(x = x,y = y)) +
              geom_point() +
              facet_grid(row ~ col);
      grob <- ggplotGrob(gg);
      

      确定要删除哪些方面以及将哪些轴移动到哪里取决于grob 的网格结构。 gtable_show_layout(grob) 给出了网格结构的可视化表示,其中(7, 4) 等数字表示7 行和4 列中的一个面板。

    3. 删除空分面。

      # Remove facets
      idx <- which(grob$layout$name %in% c("panel-2-1", "panel-3-1", "panel-3-2"));
      for (i in idx) grob$grobs[[i]] <- nullGrob();
      
    4. 向上移动 x 轴。

      # Move x axes up
      # axis-b-1 needs to move up 4 rows
      # axis-b-2 needs to move up 2 rows
      idx <- which(grob$layout$name %in% c("axis-b-1", "axis-b-2"));
      grob$layout[idx, c("t", "b")] <- grob$layout[idx, c("t", "b")] - c(4, 2);
      
    5. 将 y 轴向右移动。

      # Move y axes right
      # axis-l-2 needs to move 2 columns to the right
      # axis-l-3 needs ot move 4 columns to the right
      idx <- which(grob$layout$name %in% c("axis-l-2", "axis-l-3"));
      grob$layout[idx, c("l", "r")] <- grob$layout[idx, c("l", "r")] + c(2, 4);
      
    6. 情节。

      # Plot
      grid.newpage();
      grid.draw(grob);
      

    将其扩展到更多方面很简单。

    【讨论】:

    • 面板命名pane-2-1panel-3-1等背后的模式是什么?人们会期望它是行列的。但是,我不得不修改一个图,其中面板的排列和命名为: row1:"panel-1-1" | "panel-1-3" row2:"panel-2-1" | "panel-2-3" row3:"panel-1-2" | "panel-1-4" row4:"panel-2-2" | "panel-2-4" 是否存在一般模式或是否需要找出通过反复试验?
    • 冒着说明显而易见的风险:是否没有选项可以根据某些条件自动搜索要删除的面板?
    • @M.Teich 这是个好问题。由于确切的网格/矩阵布局取决于显示的绘图元素和位置,因此除了查看gtable_show_layout 的输出并弄清楚是什么之外,我还没有找到一种自动化的方法。要了解我的意思,请考虑将右侧分面条向左移动并观察面板名称的变化情况。
    【解决方案2】:

    当然,一种可能的解决方案是为每个因子组合分别创建一个图,然后使用来自gridExtragrid.arrange() 将它们组合起来。这可能会失去我的传奇,并且会是一个全方位的痛苦,很想听听是否有人有更好的建议。

    【讨论】:

      【解决方案3】:

      这种特殊情况看起来像是 ggpairs 的工作(link 是一个 SO 示例)。我自己没有使用过它,但对于配对图来说,这似乎是完成这项工作的最佳工具。

      在更一般的情况下,如果您不是在寻找对,您可以尝试使用复合(粘贴)因子和 facet_grid 或 facet_wrap 通过该变量创建一个列 (example)

      【讨论】:

        【解决方案4】:

        Maurits Evers 解决方案效果很好,但修改起来相当麻烦。 另一种解决方案是使用facet_manual from {ggh4x}

        这并不等同,因为它使用 facet_wrap,但允许适当放置构面。

        # devtools::install_github("teunbrand/ggh4x")
        library(ggplot2)
        
        dummy<-data.frame(x=rnorm(60),y=rnorm(60),
                          col=rep(c("A","B","C","B","C","C"),each=10),
                          row=rep(c("a","a","a","b","b","c"),each=10))
        
        design <- "
          ABC
          #DE
          ##F
        "
        
        ggplot(data=dummy,aes(x=x,y=y))+
          geom_point()+
          ggh4x::facet_manual(vars(row,col), design = design, labeller = label_both)
        

        reprex package (v2.0.0) 于 2022-02-25 创建

        【讨论】:

          猜你喜欢
          • 2017-04-09
          • 1970-01-01
          • 2017-05-09
          • 2022-01-10
          • 2022-01-01
          • 2022-07-22
          • 2020-10-13
          • 2020-05-01
          相关资源
          最近更新 更多