在R视口中使用ggplot2绘制多个图形时如何居中标题?

9

我有一个视口,里面有两个左右排列的图表。我想让一个单一的标题出现在这两个图表上方并居中于视口。这可行吗?很抱歉,因为我是新手,无法提供图片,而且由于我的工作环境原因,我也不能发布代码。


3
您可以发布一些虚构的数据与代码,或者类似的代码来展示您所拥有的内容。 - Luciano Selzer
3个回答

14
我想你可能对gridExtra包感兴趣,它提供了grid.arrange()函数,可以满足你所关注的所有内容。
在@Kevin的示例中,命令将是:
grid.arrange(plots[[1]], plots[[2]], ncol=2, 
             main="test main", sub="subtitle test")

@Kevin,你的回答很好(因此我点了+1)。在我发现这个之前,我用过你的方法 :-) - chl
@cgl 我的意思是感激的 -- 比每次需要调用函数来给一组图表加标题要简单得多(这种情况经常发生)。 - kmm
太好了!谢谢。你知道我能不能插入一张图片作为字幕吗? - pcLogos
@pcLogos 我认为是这样的,因为您可以将文本或任何“grob”传递给“sub”。请参见“?pixmapGrob”中的示例。不过,也许更简单的方法是更改网格布局,以便单独显示您的图片。 - chl

3

我一直在使用几乎未经修改的代码版本,在这篇文章中发布到了ggplot2邮件列表,以将主标题和副标题放置在一组图形矩阵的上方和下方。感谢Baptiste Auguié。

arrange <- function(..., nrow=NULL, ncol=NULL, as.table=FALSE, 
                    main=NULL, sub=NULL, plot=TRUE) { 
  dots <- list(...) 
  n <- length(dots) 
  if(is.null(nrow) & is.null(ncol)) { nrow = floor(n/2) ; ncol = ceiling(n/nrow)} 
  if(is.null(nrow)) { nrow = ceiling(n/ncol)} 
  if(is.null(ncol)) { ncol = ceiling(n/nrow)} 
  fg <- frameGrob(layout=grid.layout(nrow,ncol)) 
  ii.p <- 1 
  for(ii.row in seq(1, nrow)){ 
    ii.table.row <- ii.row       
    if(as.table) {ii.table.row <- nrow - ii.table.row + 1} 
    for(ii.col in seq(1, ncol)){ 
      ii.table <- ii.p 
      if(ii.p > n) break 
      fg <- placeGrob(fg, ggplotGrob(dots[[ii.table]]), 
                      row=ii.table.row, col=ii.col) 
      ii.p <- ii.p + 1 
    } 
  } 
  if(!is.null(main) | !is.null(sub)){ 
    g <- frameGrob() # large frame to place title(s) and content 
    g <- packGrob(g, fg) 
    if (!is.null(main)) 
      g <- packGrob(g, textGrob(main), side="top") 
    if (!is.null(sub)) 
      g <- packGrob(g, textGrob(sub), side="bottom") 
  } else { 
    g <- fg 
  } 
  if(plot) grid.draw(g) 
  invisible(g) 
} 

library(ggplot2) 
plots <- llply(1:2, function(.x) qplot(1:10,rnorm(10), main=paste("plot",.x))) 
arrange(plots[[1]],plots[[2]], nrow=1, ncol = 2, as.table=TRUE, main="test main",   
        sub="subtitle test")

产生:

示例输出。


谢谢Kevin,不过我会使用chl的建议。这样对于未来进行更改的任何人来说都更容易和更明显。 - pcLogos

1
另一种可能性是通过创建一个空白图来作弊...
p1 <- ggplot(diamonds, aes(price,depth)) + geom_point()
p2 <- ggplot(diamonds, aes(price,carat)) + geom_point()
p3 <- ggplot(diamonds, aes(x=1,y=1,label="Title")) + geom_text(size=20) + opts(panel.background=theme_blank(), panel.grid.minor=theme_blank(), panel.grid.major=theme_blank(), axis.text.x=theme_blank(), axis.text.y=theme_blank(), axis.ticks=theme_blank(), axis.title.x=theme_blank(), axis.title.y=theme_blank())
vplayout <- function(x, y) viewport(layout.pos.row=x, layout.pos.col=y)
grid.newpage()
pushViewport(viewport(layout=grid.layout(4,4)))
print(p1,vp=vplayout(2:4,1:2))
print(p2,vp=vplayout(2:4,3:4))
print(p3,vp=vplayout(1,1:4))

enter image description here


谢谢,我也想到了这个方法,但是觉得可能有一种不作弊的方式来完成它 :) 我选择了chl发布的代码。 - pcLogos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接