使用ggplot2在多图面板中设置标题

29

根据这里找到的帮助,我成功创建了这个多图面板: enter image description here 以下是代码:

library(zoo)
library(ggplot2)

datos=read.csv("paterna.dat",sep=";",header=T,na.strings="-99.9")

datos$dia=as.POSIXct(datos[,1], format="%y/%m/%d %H:%M:%S")

datos$Precipitación[is.na(datos$Precipitación)]=0
xlim = as.POSIXct(c("2010-05-12 00:00:00", "2010-05-12 23:50:00"))
ylim = trunc(max(datos$Precipitación) + 5)
tmax = trunc(max(datos$Temperatura) + 5)
tmin = trunc(min(datos$Temperatura) - 5)

tmx = max(datos$Temperatura) 
tmxpos=which.max(datos$Temperatura) 
tmn = min(datos$Temperatura) 
tmnpos=which.min(datos$Temperatura) 

tmp=ggplot(data=datos,aes(x=dia, y=Temperatura)) + geom_line(colour="red") + ylab("Temperatura (ºC)") + 
xlab(" ") + scale_x_datetime(limits=xlim ,format = "%H",major='hour') + scale_y_continuous(limits = c(tmin,tmax)) + geom_text(data=datos[tmxpos,], label=tmx, vjust=-1.5, colour="red") + geom_text(data=datos[tmnpos,], label=tmn, vjust=1.5, colour="blue")

pre=ggplot(data=datos,aes(x=dia, y=Precipitación)) + geom_bar(colour="blue",stat="identity",fill="blue") +
ylab("Precipitación (l)") + xlab("Hora solar") + scale_x_datetime(limits=xlim ,format = "%H",major='hour') + scale_y_continuous(limits=c(0,ylim))

vel=ggplot(data=datos,aes(x=dia, y=Velocidad)) + geom_line(colour="brown") + ylab("Velocidad (km/h)") + xlab(" ")  + scale_x_datetime(limits=xlim ,format = "%H",major='hour') + scale_y_continuous(limits = c(0,100))

dir=ggplot(data=datos,aes(x=dia, y=Dirección)) + geom_line(colour="brown") + ylab("Dirección viento (grados)") + xlab(" ") + scale_x_datetime(limits=xlim ,format = "%H",major='hour') + scale_y_continuous(limits = c(0,360))

hum=ggplot(data=datos,aes(x=dia, y=Humedad.Relativa)) + geom_line(colour="blue") + ylab("Humedad relativa (%)") + xlab(" ") + scale_x_datetime(limits=xlim ,format = "%H",major='hour') + scale_y_continuous(limits = c(0,100))

grid.newpage()
pushViewport(viewport(layout = grid.layout(3, 2)))   
print(tmp, vp = viewport(layout.pos.row = 1, layout.pos.col = 1))         
print(vel, vp = viewport(layout.pos.row = 1, layout.pos.col = 2))
print(dir, vp = viewport(layout.pos.row = 2, layout.pos.col = 2))
print(hum, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
print(pre, vp = viewport(layout.pos.row = 3, layout.pos.col = 1:2))

现在我缺少我想要成为气象站名称的多图的标题。我还没有找到如何在grid.newpage或viewport上设置主标题。我已经阅读了关于grid.arrange的内容,但无法弄清楚如何在我的情况下使用它。
如何完成这个任务?对你来说肯定是一个简单的问题。
您可以在http://ubuntuone.com/4G01ifn7cJ1jMIOKh中找到源数据。
提前致谢。
更新:感谢koshke,我找到了解决方案。可行的代码如下:
grid.newpage()
pushViewport(viewport(layout = grid.layout(4, 2, heights = unit(c(0.5, 5, 5, 5), "null"))))   
grid.text("MAIN TITLE", vp = viewport(layout.pos.row = 1, layout.pos.col = 1:2))
print(tmp, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))         
print(vel, vp = viewport(layout.pos.row = 2, layout.pos.col = 2))
print(dir, vp = viewport(layout.pos.row = 3, layout.pos.col = 2))
print(hum, vp = viewport(layout.pos.row = 3, layout.pos.col = 1))
print(pre, vp = viewport(layout.pos.row = 4, layout.pos.col = 1:2))

从这个文档中我找到了命令(倒数第二页),但我不确定它是否符合您的要求:grid.text("用户添加标题!", gp = gpar(fontsize = 20)) - Seb
@Seb,也许可以适应一下。我想我必须命名视口,然后寻找我想要放置文本的视口。不确定它是否会起作用,但会尝试。谢谢。 - pacomet
链接的文档描述了如何获取您要查找的视口 - 很抱歉我无法提供太多帮助,因为我没有相关经验! - Seb
尝试过但并不完全有效,它将标题绘制在页面中心,可能是因为只有一个视口。这很有前途,所以我必须深入研究视口。谢谢。 - pacomet
3个回答

28
library(gridExtra)

p <- ggplot()

grid.arrange(p,p,p,p,p, top = "Title",
            layout_matrix = matrix(c(1,2,3,4,5,5), ncol=2, byrow=TRUE))

在此输入图像描述


3
你能稍微解释一下这个吗? - Davoud Taghawi-Nejad
@DavoudTaghawi-Nejad https://github.com/baptiste/gridextra/wiki/arrangeGrob#title-andor-annotations - rawr
@rawr,恐怕这个链接已经失效了。 - DaveRGP
2
@DaveRGP 我想这个就是了,这个也可能有用。我不确定为什么 Baptiste 的仓库从他的 Github 页面上消失了。 - rawr

23

如果我正确理解你想做什么,那么你可以使用+opts(title=XXX)

p1 <- ggplot(mtcars, aes(factor(cyl))) + geom_bar()
p2 <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
p3 <- p2 + geom_line()

pushViewport(viewport(layout = grid.layout(2, 2)))  
print(p1 + opts(title = "bar"), 
  vp = viewport(layout.pos.row = 1, layout.pos.col = 1))     
print(p2 + opts(title = "point"), 
  vp = viewport(layout.pos.row = 1, layout.pos.col = 2))     
print(p3 + opts(title = "point and line"), 
  vp = viewport(layout.pos.row = 2, layout.pos.col = 1:2))

输入图像描述

更新

这里有一个例子:

pushViewport(viewport(layout = grid.layout(3, 2, heights = unit(c(1, 4, 4), "null"))))
grid.text("title of this panel", vp = viewport(layout.pos.row = 1, layout.pos.col = 1:2))
print(p1, vp = viewport(layout.pos.row = 2, layout.pos.col = 1))
print(p2, vp = viewport(layout.pos.row = 2, layout.pos.col = 2))
print(p3, vp = viewport(layout.pos.row = 3, layout.pos.col = 1:2))

你需要做的是:

  1. 在格子布局中添加一行
  2. 调整宽度
  3. 在额外的视口行上绘制textGrob。

enter image description here


这不是我需要的,也许我没有解释清楚。数据来自气象站,然后我想把站名和日期(标题)放在面板顶部。我不需要每个图表都有一个标题(我从第一次尝试中删除了它们),因为y轴也命名了图表。谢谢。 - pacomet
好的,我已经更新了。目前来看,ggplot2 的布局并不是很直观。也许将来会更容易些。 - kohske

1
现在,您可以使用非常有用的patchwork包轻松地将多个图形组合成一个图形。要向多个图形添加主标题,您可以使用plot_annotation。这里是一个可重现的例子,使用mtcars数据集:
library(ggplot2)
library(patchwork)
p1 <- ggplot(mtcars, aes(hp, mpg)) +           
  geom_point() +
  ggtitle("title 1")
p2 <- ggplot(mtcars, aes(qsec)) +
  geom_density() +
  ggtitle("title 2")
p3 <- ggplot(mtcars, aes(wt)) +
  geom_histogram() +
  ggtitle("title 3")
p4 <- ggplot(mtcars, aes(cyl, carb)) +
  geom_bar(stat = "identity") +
  ggtitle("title 4")

p_all <- (p1 + p2) / (p3 + p4) +    
  plot_annotation(title = "Main title of Multiplot") & 
  theme(plot.title = element_text(hjust = 0.5))

p_all 

创建于2022年8月19日,使用reprex v2.0.2

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