添加轴标题后停止ggplots调整大小

时间:2018-10-15 08:36:48

标签: r ggplot2

我有一个具有4 x 3面板结构的ggplot2。面板的每一列共享相同的x轴文本和标题。我希望所有面板的尺寸都相同,但是当我在底部一行添加x轴标题和文本时,它会导致面板尺寸调整。如何确保面板尺寸相等?下面给出了一个可重现的示例:

library(ggmap)
library(maps)
library(ggplot2)

BII.TEMP.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "Temp"=c(8,7,8,9))
BII.PPT.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "PPT"=c(8,7,8,9))
SCAN.TEMP.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "Temp"=c(8,7,8,9))
SCAN.PPT.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "PPT"=c(8,7,8,9))
CE.TEMP.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "Temp"=c(8,7,8,9))
CE.PPT.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "PPT"=c(8,7,8,9))
TEMP.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "Temp"=c(8,7,8,9))
PPT.SUMMER=data.frame("Year"=c(1851, 1901, 1951, 2001), "PPT"=c(8,7,8,9))



BII.coords=data.frame(lon=c(-6.9532,-7.9925,-2.5036,-8.2569,-6.5487,-7.4083,-2.0369,-2.175,-6.1921), 
                          lat=c(53.3653,53.0807,55.0875,53.1865,54.8862,53.7667,54.4253,54.0964,55.0848))

CE.coords=data.frame(lon=c(16.5872,13.8494,6.2317,21.2201,15.3602,17.9821,18.3098,
                           9.8544,22.4419,6.1736,16.4785,18.0833,24.545), 
                     lat=c(53.8078,53.0558,46.5397,53.8726,50.8519,53.5918,53.188,
                           46.49,54.3314,46.5667,54.3619,54.4244,47.5739))

SCAN.coords=data.frame(lon=c(17.3667,18.6833,18.4333,22.7833,19.5828,10.1896,26.25,19.0484), 
                       lat=c(60.0167,59.9667,59.6333,60.7833,64.1647,56.8391,58.8667,68.3568))

BII.MAP=data.frame(xmin=-10.31, xmax=-0.93, ymin=51.44, ymax=55.22)
thismap=map_data("world")
P1=ggplot()+geom_polygon(data=thismap, aes(x=long, y=lat, group=group), color="lightgray", fill="white")+
  coord_fixed(xlim=c(-11, 30), ylim=c(40, 70), ratio=1.0)+
  geom_rect(data=BII.MAP, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
            inherit.aes=FALSE, colour="black", alpha=0.1)+
  geom_point(data=BII.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=0)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="black", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  ggtitle("Britain & Ireland")

SCAN.MAP=data.frame(xmin=8.44, xmax=27.19, ymin=55.25, ymax=68.56)
thismap=map_data("world")
P4=ggplot()+geom_polygon(data=thismap, aes(x=long, y=lat, group=group), color="lightgray", fill="white")+
  coord_fixed(xlim=c(-11, 30), ylim=c(40, 70), ratio=1.0)+
  geom_point(data=SCAN.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=1)+
  geom_rect(data=SCAN.MAP, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
            inherit.aes=FALSE, colour="black", alpha=0.1)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="black", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  ggtitle("Scandinavia")

CE.MAP=data.frame(xmin=4.69, xmax=25.32, ymin=45.73, ymax=55.22)
thismap=map_data("world")
P7=ggplot()+geom_polygon(data=thismap, aes(x=long, y=lat, group=group), color="lightgray", fill="white")+
  coord_fixed(xlim=c(-11, 30), ylim=c(40, 70), ratio=1.0)+
  geom_point(data=CE.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=2)+
  geom_rect(data=CE.MAP, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
            inherit.aes=FALSE, colour="black", alpha=0.1)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="black", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  ggtitle("Continental Europe")

MAP=data.frame(xmin=-10.31, xmax=27.19, ymin=45.73, ymax=68.56)
thismap=map_data("world")
P10=ggplot()+geom_polygon(data=thismap, aes(x=long, y=lat, group=group), color="lightgray", fill="white")+
  coord_fixed(xlim=c(-11, 30), ylim=c(40, 70), ratio=1.0)+
  geom_point(data=BII.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=0)+
  geom_point(data=SCAN.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=1)+
  geom_point(data=CE.coords, aes(lon, lat), inherit.aes=FALSE, color="black", size=2, shape=2)+
  geom_rect(data=MAP, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
            inherit.aes=FALSE, colour="black", alpha=0.1)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="black", size=10, face="bold"), 
        axis.ticks.length=unit(0.2, "cm"))+
  ggtitle("All Sites")

P2=ggplot(BII.TEMP.SUMMER, aes(Year,Temp))+
  geom_line(color="gray75")+ylim(12.9,16.6)+geom_smooth(color="red", se=FALSE)+ggtitle("Temperatures (°C)")+
  geom_vline(xintercept=1914, col="purple4", linetype=2)+annotate("text", x=1916, y=12.9, label="Dry Shift", col="purple4")+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="red", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=16.6)

P3=ggplot(BII.PPT.SUMMER, aes(Year,PPT))+
  geom_line(color="gray75")+ylim(88,428)+geom_smooth(color="blue", se=FALSE)+ggtitle("Precipitation (mm)")+
  geom_vline(xintercept=1914, col="purple4", linetype=2)+annotate("text", x=1916, y=88, label="Dry Shift", col="purple4")+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="blue", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=428)

P5=ggplot(SCAN.TEMP.SUMMER, aes(Year,Temp))+
  geom_line(color="gray75")+ylim(11.2,16.2)+geom_smooth(color="red", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=16.2)+
  ggtitle("BLANK")

P6=ggplot(SCAN.PPT.SUMMER, aes(Year,PPT))+
  geom_line(color="gray75")+ylim(144,359)+geom_smooth(color="blue", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=359)+
  ggtitle("BLANK")

P8=ggplot(CE.TEMP.SUMMER, aes(Year,Temp))+
  geom_line(color="gray75")+ylim(16.4,21.3)+geom_smooth(color="red", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=21.3)+
  ggtitle("BLANK")

P9=ggplot(CE.PPT.SUMMER, aes(Year,PPT))+
  geom_line(color="gray75")+ylim(144, 387)+geom_smooth(color="blue", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.text.x=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=387)+
  ggtitle("BLANK")

P11=ggplot(TEMP.SUMMER, aes(Year,Temp))+
  geom_line(color="gray75")+ylim(13.9,17.6)+geom_smooth(color="red", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=17.6)+
  ggtitle("BLANK")

P12=ggplot(PPT.SUMMER, aes(Year,PPT))+
  geom_line(color="gray75")+ylim(139,328)+geom_smooth(color="blue", se=FALSE)+
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(), plot.title=element_text(color="white", size=10, face="bold"), 
        axis.title.y=element_blank(), axis.ticks.length=unit(0.2, "cm"))+
  annotate("text", x=1935, y=328)+
  ggtitle("BLANK")

plots <- list(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
grobs <- list()
widths <- list()

#collect the widths for each grob of each plot
for (i in 1:length(plots)){
  grobs[[i]] <- ggplotGrob(plots[[i]])
  widths[[i]] <- grobs[[i]]$widths[2:5]
}

#use do.call to get the max width
maxwidth <- do.call(grid::unit.pmax, widths)

#asign the max width to each grob
for (i in 1:length(grobs)){
  grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}

# plot
#do.call("grid.arrange", c(grobs, ncol = 1))
do.call("grid.arrange", c(grobs, nrow = 4))

2 个答案:

答案 0 :(得分:4)

另一种解决方案是使用patchwork包(来自github的thomasp85/patchwork),您做起来并不容易。

我无法绘制图形P2,P3,P5,P6,P8,P9,P11和P12,所以我创建了模拟数据。

# mock data 
library(tidyverse)
data <- lapply(c(2,3,5,6,8,9,11,12), function(k) {
  data.frame(x = seq(1, 100, 1),
             y = runif(100, 0, 50),
             label = k) %>%
    ggplot(., aes(x, y)) +
    geom_point() +
    geom_smooth(method = "lm", se = FALSE) +
    ggtitle(k) +
    theme(axis.ticks.length = unit(0.2, "cm"))
})

p2 <- data[[1]] +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_blank())

p3 <- data[[2]] +
  theme(axis.title = element_blank(),
        axis.text.x = element_blank())

p5 <- data[[3]] +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_blank())

p6 <- data[[4]] +
  theme(axis.title = element_blank(),
        axis.text.x = element_blank())

p8 <- data[[5]] +
  theme(axis.title.x = element_blank(),
        axis.text.x = element_blank())

p9 <- data[[6]] +
  theme(axis.title = element_blank(),
        axis.text.x = element_blank())


p11 <- data[[7]] 

p12 <- data[[8]] +
  theme(axis.title.y = element_blank())

这是剧情的代码:

devtools::install_github("thomasp85/patchwork")
library(patchwork)
# PLOT
P1 + p2 + p3 + 
  P4 + p5 + p6 + 
  P7 + p8 + p9 + 
  P10 + p11 + p12 + 
  plot_layout(ncol = 3)

plot

答案 1 :(得分:1)

这个来自@slizb的优雅清晰的答案几乎可以完全满足您的要求:   https://stackoverflow.com/a/19321139/10312356

唯一的区别是,@ slizb在该示例中显示的解决方案是针对单列网格布局,而您想要的是4行乘3列的布局。

所有对@slizb的贡献如下所示,我只添加了您的数据,并在最后一行将ncol = 1更改为nrow = 4。

如果这可以解决您的问题,请在另一个问题中对@slizb进行投票,而不要对这个答案进行投票,因为我不能因为如此琐碎的编辑而获得赞誉。

plots <- list(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
grobs <- list()
widths <- list()

#collect the widths for each grob of each plot

for (i in 1:length(plots)){
  grobs[[i]] <- ggplotGrob(plots[[i]])
  widths[[i]] <- grobs[[i]]$widths[2:5]
}

#use do.call to get the max width

maxwidth <- do.call(grid::unit.pmax, widths)

#asign the max width to each grob

for (i in 1:length(grobs)){
  grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}

# plot

#do.call("grid.arrange", c(grobs, ncol = 1))
do.call("grid.arrange", c(grobs, nrow = 4))

enter image description here