使用facet_grid的每个子图的y轴

时间:2016-06-03 16:40:20

标签: r ggplot2 gtable grob facet-grid

我无法得到这个问题的答案。 我和该用户想要的是在使用facet_grid()时向所有列添加轴刻度和标签。

Display y-axis for each subplot when faceting

当我运行可重现的示例和解决方案(在添加abc = as.data.frame(abc)以修复初始错误之后)我收到错误消息

  

gtable_add_grob中的错误(g,grobs = list(segmentsGrob(1,0,1,1),   segmentsGrob(1,:并非所有输入都具有长度1或相同   长度与' grobs相同

我做了我自己的可重复的例子,因为原来的是ehhm,有点奇怪:-)。它会产生相同的错误消息

require(ggplot2)
require(reshape)
require(grid)
require(gtable)
data(iris)
iris$category=rep(letters[1:4],length.out=150)
plot1=ggplot(data=iris,aes(x=1,y=Sepal.Width))+geom_boxplot()+facet_grid(Species~category)

答案应该是:

g <- ggplotGrob(plot1)

require(gtable)
axis <- gtable_filter(g, "axis-l")[["grobs"]][[1]][["children"]][["axis"]][,2]
segment <- segmentsGrob(1,0,1,1)
panels <- subset(g$layout, name == "panel")
g <- gtable_add_grob(g, grobs=list(axis, axis), name="ticks",
                     t = unique(panels$t), l=tail(panels$l, -1)-1)

g <- gtable_add_grob(g, grobs=list(segmentsGrob(1,0,1,1), 
                                   segmentsGrob(1,0,1,1)), 
                     t = unique(panels$t), l=tail(panels$l, -1)-1, 
                     name="segments")

2 个答案:

答案 0 :(得分:2)

这就是我提出的(使用ggplot2_2.1.0):

g <- ggplotGrob(plot1)
axis <- gtable_filter(g, "axis-l")
newG <- gtable_add_grob(g, list(axis, axis, axis), 
                t = rep(4, 3), b = rep(8, 3), l = c(5, 7, 9))
grid.draw(newG)

..看起来像这样:

enter image description here

这是我经历的过程:

  1. g <- ggplotGrob(plot1)创建一个gtable。
  2. print(g)查看gtable的元素......我正在寻找我想弄乱的grobs的名字。在这里,它是三个叫做&#34; axis-l&#34;的grob。
  3. axis <- gtable_filter(g, "axis-l")我从较大的gtable对象g中选择我的三个grobs,并将它们保存在名为axis的gtable中。请注意,gtable_filter实际上是在选择grobs,而不是从g过滤它们。
  4. gtable_show_layout(g)查看g的布局,以便了解我希望axis与整体情节的关系。
  5. gtable_add_grob等等。既然我知道我要去哪里,我可以用axis追加原始情节。
  6. 我认为这些步骤在gtable方面是一个非常常见的工作流程。当然,你还有其他东西,你可能会搞乱。例如,在这种情况下,除了最左边的y轴标签之外的所有空间都给出了空间。也许只是:

    newG$widths[c(5, 7, 9)] <- grid:::unit.list(axis$widths) # you won't need to wrap this in grid
    grid.draw(newG)
    

    enter image description here

答案 1 :(得分:2)

您所指的答案并不适用于您的情况。

为了更好地放置刻度线和刻度线标签,我会在gtable中添加列以获取轴材质。新列的宽度与原始y轴的宽度相同。

您可能希望在面板之间添加更多边距空间。使用theme(panel.margin.x = unit(1, "lines"))执行此操作。

require(ggplot2)
require(grid)
require(gtable)
data(iris)
iris$category = rep(letters[1:4], length.out = 150)
plot1 = ggplot(data = iris, aes(x = 1, y = Sepal.Width))+
   geom_boxplot()+
   facet_grid(Species~category)

# Get the ggplot grob
g <- ggplotGrob(plot1)

# Get the yaxis
yaxis <- gtable_filter(g, "axis-l")

# Get the width of the y axis
Widths = yaxis$widths

# Add columns to the gtable to the left of the panels, 
# with a width equal to yaxis width
panels <- g$layout[grepl("panel", g$layout$name), ]
pos = rev(unique(panels$l)[-1] - 1)
for(i in pos) g = gtable_add_cols(g, Widths, i)

# Add y axes to the new columns
panels <- g$layout[grepl("panel", g$layout$name), ]
posx = rev(unique(panels$l)[-1] - 1)
posy = unique(panels$t)

g = gtable_add_grob(g, rep(list(yaxis), length(posx)), 
     t = rep(min(posy), length(posx)), b = rep(max(posy), length(posx)), l = posx)

# Draw it
grid.newpage()
grid.draw(g)

enter image description here

或者,将轴放在与原始y轴相同宽度的视口中,但右对齐。然后,将生成的grob添加到面板之间的现有边距列,调整这些列的宽度以适应。

require(ggplot2)
require(grid)
require(gtable)
data(iris)
iris$category = rep(letters[1:4], length.out = 150)
plot1 = ggplot(data = iris, aes(x = 1, y = Sepal.Width))+
   geom_boxplot() + 
   facet_grid(Species ~ category ) 

# Get the ggplot grob
g <- ggplotGrob(plot1)

# Get the yaxis
axis <- gtable_filter(g, "axis-l")

# Get the width of the y axis
Widths = axis$width

# Place the axis into a viewport, 
# of width equal to the original yaxis material,
# and positioned to be right justified
axis$vp = viewport(x = unit(1, "npc"), width = Widths, just = "right")

# Add y axes to the existing margin columns between the panels
panels <- g$layout[grepl("panel", g$layout$name), ] 
posx = unique(panels$l)[-1] - 1
posy = unique(panels$t)

g = gtable_add_grob(g, rep(list(axis), length(posx)), 
     t = rep(min(posy), length(posx)), b = rep(max(posy), length(posx)), l = posx)

# Increase the width of the margin columns
g$widths[posx] <- unit(25, "pt") 
# Or increase width of the panel margins in the original construction of plot1

# Draw it
grid.newpage()
grid.draw(g)