每个子图的 y 轴使用 facet_grid
y-axis for each subplot using facet_grid
我无法得到这个问题的答案。
我和那个用户都想要的是在使用 facet_grid() 时向所有列添加轴刻度和标签。
Display y-axis for each subplot when faceting
当我 运行 可重现的示例和解决方案(添加 abc=as.data.frame(abc) 以修复初始错误后)时,我收到一条错误消息
Error in gtable_add_grob(g, grobs = list(segmentsGrob(1, 0, 1, 1),
segmentsGrob(1, : Not all inputs have either length 1 or same
length same as 'grobs
我制作了自己的可重现示例,因为原始示例有点奇怪 :-)。它导致相同的错误消息
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")
这就是我想到的(使用 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)
..看起来像这样:
这是我经历的过程:
g <- ggplotGrob(plot1)
创建一个 gtable。
print(g)
查看 gtable 的元素...我正在寻找我想弄乱的 grobs 的名称。在这里,就是三个叫 "axis-l" 的 grob。
axis <- gtable_filter(g, "axis-l")
我 select 从较大的 gtable 对象 g
中获取我的三个 grob,并将它们保存在名为 axis
的 gtable 中。请注意,gtable_filter
实际上是 select 抓取,而不是从 g
中过滤它们。
gtable_show_layout(g)
查看 g
的布局,这样我就可以弄清楚 axis
与整个情节的关系。
gtable_add_grob
,等等。现在我知道我要去哪里了,我可以在原始情节上附加 axis
。
我认为就 gtable 而言,这些步骤是非常常见的工作流程。当然,您还会有其他东西,您可能会弄乱这些东西。例如,在这种情况下,为除最左边的 y 轴标签之外的所有标签提供的 space 是不够的。所以也许只是:
newG$widths[c(5, 7, 9)] <- grid:::unit.list(axis$widths) # you won't need to wrap this in grid
grid.draw(newG)
您提到的答案不适用于您的情况。
为了更好地放置刻度线和刻度线标签,我会向 gtable 添加列以获取轴 material。新列的宽度与原始 y 轴相同。
您可能想要在面板之间添加更多边距 space。用 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)
或者,将轴放置在与原始 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)
我无法得到这个问题的答案。 我和那个用户都想要的是在使用 facet_grid() 时向所有列添加轴刻度和标签。
Display y-axis for each subplot when faceting
当我 运行 可重现的示例和解决方案(添加 abc=as.data.frame(abc) 以修复初始错误后)时,我收到一条错误消息
Error in gtable_add_grob(g, grobs = list(segmentsGrob(1, 0, 1, 1), segmentsGrob(1, : Not all inputs have either length 1 or same length same as 'grobs
我制作了自己的可重现示例,因为原始示例有点奇怪 :-)。它导致相同的错误消息
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")
这就是我想到的(使用 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)
..看起来像这样:
这是我经历的过程:
g <- ggplotGrob(plot1)
创建一个 gtable。print(g)
查看 gtable 的元素...我正在寻找我想弄乱的 grobs 的名称。在这里,就是三个叫 "axis-l" 的 grob。axis <- gtable_filter(g, "axis-l")
我 select 从较大的 gtable 对象g
中获取我的三个 grob,并将它们保存在名为axis
的 gtable 中。请注意,gtable_filter
实际上是 select 抓取,而不是从g
中过滤它们。gtable_show_layout(g)
查看g
的布局,这样我就可以弄清楚axis
与整个情节的关系。gtable_add_grob
,等等。现在我知道我要去哪里了,我可以在原始情节上附加axis
。
我认为就 gtable 而言,这些步骤是非常常见的工作流程。当然,您还会有其他东西,您可能会弄乱这些东西。例如,在这种情况下,为除最左边的 y 轴标签之外的所有标签提供的 space 是不够的。所以也许只是:
newG$widths[c(5, 7, 9)] <- grid:::unit.list(axis$widths) # you won't need to wrap this in grid
grid.draw(newG)
您提到的答案不适用于您的情况。
为了更好地放置刻度线和刻度线标签,我会向 gtable 添加列以获取轴 material。新列的宽度与原始 y 轴相同。
您可能想要在面板之间添加更多边距 space。用 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)
或者,将轴放置在与原始 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)