我有两个图表,我将它们放在另一个之上,方式如下:
library(ggplot2)
library(gridExtra)
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- p2 + facet_grid(cyl ~ .)
grid.arrange(p1, p2, ncol=1)
为此我需要顶部和底部图形的x轴排成一行,但是由于左边的条带,刻面图比顶部图更窄。我可以使用以下方法使条带不可见:
theme(strip.text.y = element_blank())
theme(strip.background = element_blank())
然而,这并没有摆脱条带占据的空间。所以我要么需要一种方法来完全摆脱条带,或者有办法将我的分面图分割成单独的图形,但不知何故在它们之间共享相同的y轴标签。在我的图表中,我有两个不高的面板,并且没有足够的空间让每个面板都有一个像样的y轴。
有什么建议吗?
答案 0 :(得分:8)
我的解决方案是找到条带的宽度,然后将两个图形的边距设置为零,但是将没有条带的边缘缩小到略小(条带的宽度),以便它们出现大小相同。通过反复试验,似乎条带大约是0.5行宽(但我猜你可以用编程方式来解决这个问题)。因此,只需确保图中没有条形文本的正确的绘图边距比不可见条带大0.5行:
# Add a line of width 0.5 on the left but set all other margins to zero
p1 <- p1 + theme( plot.margin = unit( c(0,0.5,0,0) , units = "lines" ) )
# Set all margins to zero, the strip will take up a phantom amount of invisible space
p2 <- p2 + theme(strip.text.y = element_blank() ,
strip.background = element_blank(),
plot.margin = unit( c(0,0,0,0) , units = "lines" ) )
grid.arrange(p1, p2, ncol=1)
显然你可以根据需要调整边距(例如,在plot.margin
中的每个数字向量的第一个位置加1,以获得每个图顶部一行的边框),只要你保持在第二个图的右边界中,0.5行更多的边距,它们看起来是一样的。
答案 1 :(得分:1)
这是使用viewport
和grid.layout
的另一种解决方案。我创建了2个具有2种不同布局的视口。然后我使用参数vp放置ggplot2图。
library(grid)
pushViewport(plotViewport(c(1,1,1,1),layout = grid.layout(2, 1)))
print(p2, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
pushViewport(viewport(layout.pos.row=1,
layout = grid.layout(1, 2,widths = unit(c(1,1),c("null",'lines')))))
print(p1, vp = viewport(layout.pos.row = 1, layout.pos.col = 1))
upViewport(2)
答案 2 :(得分:1)
您也可以这样做,并保留条带标题,这将是相关的信息:
library(ggplot2)
library(gridExtra)
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
xlab(NULL)
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
facet_wrap( ~ cyl, ncol = 1)
grid.arrange(p1, p2, ncol=1)
答案 3 :(得分:1)
使用gtable
包中的函数的另一种解决方案。它对齐图表但保留条带文本。它使用gtable
函数在p1
右侧插入一列等于p2
条带文本的宽度。
library(ggplot2)
library(gridExtra)
library(gtable)
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- p2 + facet_grid(cyl ~ .)
g1 = ggplotGrob(p1)
# gtable_show_layout(g1) # View the layout
# g1$widths # Get the widths of g1
g2 = ggplotGrob(p2)
# gtable_show_layout(g2) # View the layout
# g2$widths # Check the widths of g2
# Add new column to the right of g1 equal in width the strip width of g2.
# In g2, strip width is the 6th element the vector g2$widths
g1 <- gtable_add_cols(g1, g2$widths[6])
grid.arrange(g1, g2, ncol=1)
## But note that if the y-axis titles and/or labels take up different widths,
# the two plots are not aligned
p1 <- ggplot(mtcars, aes(mpg, wt)) + geom_point() +
theme(axis.title.y = element_text(vjust = .5, angle = 0, size = 30))
p2 <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p2 <- p2 + facet_grid(cyl ~ .)
g1 = ggplotGrob(p1)
g2 = ggplotGrob(p2)
g1 <- gtable_add_cols(g1, g2$widths[6]) # New column added to the right
grid.arrange(g1, g2, ncol=1) # Plots are not aligned
# Need to set widths to the maximums in the two plots,
# i.e., set g2 widths to be the same as g1 widths
g2$widths <- g1$widths
grid.arrange(g1, g2, ncol=1) # Plots are aligned
编辑或按照baptiste的建议,使用gtable
的{{1}}函数:
rbind()