如何使用facet_grid或facet_wrap保持条的均匀厚度并切换条的位置?

时间:2018-08-17 14:53:31

标签: r ggplot2

我想用水平条形图显示数据,并用分组变量对其进行分面。由于我想要带有刻面的水平图形,因此我将使用geom_barh包中的ggstance。我有一个数据集,我的观察结果分为几种不同的计数类型。像这样:

library(tidyverse)

data <- tibble(observations = c(1:17), 
           type = c("a", "a", "a", "a", 
                    "b", "b", "b", "b", "b", "b", 
                    "c", "c", "c", "c", "c", "c", "c"),
           n = c(30:46))

这是我的问题。当我使用facet_wrap时,我的条具有不同的宽度:

library(ggstance)    

ggplot(data, aes(x = n, y = reorder(observations, n))) +
 geom_barh(stat = "identity") +
 facet_wrap(~ type, ncol = 1, scales = "free_y")

enter image description here

但是当我使用facet_grid时,由于没有strip.position参数,我无法将工具条移到顶部:

ggplot(data, aes(x = n, y = reorder(observations, n))) +
 geom_barh(stat = "identity") +
 facet_grid(type ~ . , scales = "free_y", space = "free_y")

enter image description here

这仅仅是ggplot的怪癖之一,还是有办法操纵它?

1 个答案:

答案 0 :(得分:3)

我不认为ggplot2是用于此目的的,但是像许多其他情况一样,如果您愿意接受grob(而不是ggplot2对象)作为最终结果,则可以破解解决方案。

这里的基本思想是facet_wrap()允许条带位于任何位置(顶部/左侧/右侧/底部),而fact_grid()允许面板的高度/宽度不同。如果我们将每个选项的ggplot2结果转换为grob对象,则可以将选项2的面板高度应用于选项1。方法如下:

步骤1 。同时基于facet_wrap()facet_grid()创建ggplot2对象。将它们转换为grob对象。 (注意:我没有安装ggstance软件包,但是通常的geom_col() + coord_flip()应该是相似的,以便在此处说明概念...)

p1 <- ggplot(data, aes(y = n, x = reorder(observations, n))) +
  geom_col() +
  facet_wrap(~ type, ncol = 1, scales = "free_y") +
  coord_flip()
g1 <- ggplotGrob(p1)

p2 <- ggplot(data,
       aes(y = n, x = reorder(observations, n))) +
  geom_col() +
  facet_grid(type ~ . , scales = "free_y", space = "free_y") +
  coord_flip()
g2 <- ggplotGrob(p2)

第2步。获取面板行在g1和g2的布局中的位置:

g1.panel.rows <- g1$layout$t[grep("panel", g1$layout$name)] #7 / 12 / 17 in this case
g2.panel.rows <- g2$layout$t[grep("panel", g2$layout$name)] #6 / 8 / 10 in this case

# optional: view the layout & visually check that the above are correct
gtable::gtable_show_layout(g1)
gtable::gtable_show_layout(g2)

# also optional (but recommended): check the current height associated with each panel;
# note that g1 has equal height for each panel, while g2 does not    
> g1$heights[g1.panel.rows]
[1] 1null 1null 1null
> g2$heights[g2.panel.rows]
[1] 4.2null 6.2null 7.2null

第3步。将g2的面板高度应用于g1的面板并查看结果。

g1$heights[g1.panel.rows] <- g2$heights[g2.panel.rows]
grid::grid.draw(g1)

plot