r - 如何对齐多个ggplot2图并在所有图上添加阴影

标签 r ggplot2

Please download the data here!

目标:绘制这样的图像:

this

特色:
1.两个不同的时间序列;
2. 下面板有一个反向的y轴;
3. 两个地 block 上的阴影。

可能的解决方案:
1. 刻面不合适 - (1) 不能只使一个刻面的 y 轴反转而保持其他刻面不变。 (2) 难以一一调整个别方面。
2. 使用视口(viewport)使用以下代码排列单个绘图:

library(ggplot2)
library(grid)
library(gridExtra)

##Import data
df<- read.csv("D:\\R\\SF_Question.csv")

##Draw individual plots
#the lower panel
p1<- ggplot(df, aes(TIME1, VARIABLE1)) + geom_line() + scale_y_reverse() + labs(x="AGE") + scale_x_continuous(breaks = seq(1000,2000,200), limits = c(1000,2000))
#the upper panel
p2<- ggplot(df, aes(TIME2, V2)) + geom_line() + labs(x=NULL) + scale_x_continuous(breaks = seq(1000,2000,200), limits = c(1000,2000)) + theme(axis.text.x=element_blank())

##For the shadows
#shadow position
rects<- data.frame(x1=c(1100,1800),x2=c(1300,1850),y1=c(0,0),y2=c(100,100))
#make shadows clean (hide axis, ticks, labels, background and grids)
xquiet <- scale_x_continuous("", breaks = NULL)
yquiet <- scale_y_continuous("", breaks = NULL)
bgquiet<- theme(panel.background = element_rect(fill = "transparent", colour = NA))
plotquiet<- theme(plot.background = element_rect(fill = "transparent", colour = NA))
quiet <- list(xquiet, yquiet, bgquiet, plotquiet)
prects<- ggplot(rects,aes(xmin=x1,xmax=x2,ymin=y1,ymax=y2))+ geom_rect(alpha=0.1,fill="blue") + coord_cartesian(xlim = c(1000, 2000)) + quiet

##Arrange plots
pushViewport(viewport(layout = grid.layout(2, 1)))
vplayout <- function(x, y) 
  viewport(layout.pos.row = x, layout.pos.col = y)
#arrange time series
print(p2, vp = vplayout(1, 1))
print(p1, vp = vplayout(2, 1))
#arrange shadows
print(prects, vp=vplayout(1:2,1))

this

问题:
  • x 轴未正确对齐;
  • 阴影位置错误(因为 x 轴排列不正确)。

  • 谷歌搜索后:
  • 我首先注意到“ggExtra 中的 align.plots()”可以完成这项工作。但是,它已被作者弃用;
  • 然后我尝试了gglayout solution ,但没有运气——我什至无法安装“尖端”包;
  • 最后,我尝试了gtable solution使用以下代码:
    gp1<- ggplot_gtable(ggplot_build(p1))
    gp2<- ggplot_gtable(ggplot_build(p2))
    gprects<- ggplot_gtable(ggplot_build(prects))
    maxWidth = unit.pmax(gp1$widths[2:3], gp2$widths[2:3], gprects$widths[2:3])
    gp1$widths[2:3] <- maxWidth
    gp2$widths[2:3] <- maxWidth
    gprects$widths[2:3] <- maxWidth
    grid.arrange(gp2, gp1, gprects)
    

  • this

    现在,上下面板的 x 轴确实对齐了。但影子位置仍然是错误的。更重要的是,我不能在两个时间序列上重叠阴影图。经过几天的尝试,我几乎放弃了......

    有人可以帮帮我吗?

    最佳答案

    您也可以仅使用基本绘图功能来实现此特定绘图。

    #Set alignment for tow plots. Extra zeros are needed to get space for axis at bottom.
    layout(matrix(c(0,1,2,0),ncol=1),heights=c(1,3,3,1))
    
    #Set spaces around plot (0 for bottom and top)
    par(mar=c(0,5,0,5))
    
    #1. plot
    plot(df$V2~df$TIME2,type="l",xlim=c(1000,2000),axes=F,ylab="")
    
    #Two rectangles - y coordinates are larger to ensure that all space is taken  
    rect(1100,-15000,1300,15000,col="red",border="red")
    rect(1800,-15000,1850,15000,col="red",border="red")
    
    #plot again the same line (to show line over rectangle)
    par(new=TRUE)
    plot(df$V2~df$TIME2,type="l",xlim=c(1000,2000),axes=F,ylab="")
    
    #set axis
    axis(1,at=seq(800,2200,200),labels=NA)
    axis(4,at=seq(-15000,10000,5000),las=2)
    
    
    #The same for plot 2. rev() in ylim= ensures reverse axis.
    plot(df$VARIABLE1~df$TIME1,type="l",ylim=rev(range(df$VARIABLE1)+c(-0.1,0.1)),xlim=c(1000,2000),axes=F,ylab="")
    rect(1100,-15000,1300,15000,col="red",border="red")
    rect(1800,-15000,1850,15000,col="red",border="red")
    par(new=TRUE)
    plot(df$VARIABLE1~df$TIME1,type="l",ylim=rev(range(df$VARIABLE1)+c(-0.1,0.1)),xlim=c(1000,2000),axes=F,ylab="")
    axis(1,at=seq(800,2200,200))
    axis(2,at=seq(-6.4,-8.4,-0.4),las=2)
    

    enter image description here

    更新 - ggplot2 的解决方案

    首先,制作两个包含矩形信息的新数据框。
    rect1<- data.frame (xmin=1100, xmax=1300, ymin=-Inf, ymax=Inf)
    rect2 <- data.frame (xmin=1800, xmax=1850, ymin=-Inf, ymax=Inf)
    

    修改了您的原始情节代码 - 移动 dataaes到里面geom_line() ,然后添加两个 geom_rect()来电。最重要的部分是plot.margin=theme() .对于每个图,我将其中一个边距设置为 -1线(p1 的上部和 p2 的底部) - 这将确保情节将加入。所有其他边距应该相同。对于 p2还删除了轴刻度。然后将两个图放在一起。
    library(ggplot2)
    library(grid)
    library(gridExtra)
    p1<- ggplot() + geom_line(data=df, aes(TIME1, VARIABLE1)) + 
      scale_y_reverse() + 
      labs(x="AGE") + 
      scale_x_continuous(breaks = seq(1000,2000,200), limits = c(1000,2000)) + 
       geom_rect(data=rect1,aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax),alpha=0.1,fill="blue")+
       geom_rect(data=rect2,aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax),alpha=0.1,fill="blue")+
       theme(plot.margin = unit(c(-1,0.5,0.5,0.5), "lines"))
    
    p2<- ggplot() + geom_line(data=df, aes(TIME2, V2)) + labs(x=NULL) + 
      scale_x_continuous(breaks = seq(1000,2000,200), limits = c(1000,2000)) + 
      scale_y_continuous(limits=c(-14000,10000))+
      geom_rect(data=rect1,aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax),alpha=0.1,fill="blue")+
      geom_rect(data=rect2,aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax),alpha=0.1,fill="blue")+
      theme(axis.text.x=element_blank(),
            axis.title.x=element_blank(),
            plot.title=element_blank(),
            axis.ticks.x=element_blank(),
            plot.margin = unit(c(0.5,0.5,-1,0.5), "lines"))
    
    
    gp1<- ggplot_gtable(ggplot_build(p1))
    gp2<- ggplot_gtable(ggplot_build(p2))
    maxWidth = unit.pmax(gp1$widths[2:3], gp2$widths[2:3])
    gp1$widths[2:3] <- maxWidth
    gp2$widths[2:3] <- maxWidth
    grid.arrange(gp2, gp1)
    

    enter image description here

    关于r - 如何对齐多个ggplot2图并在所有图上添加阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15016995/

    相关文章:

    r - 当隐含ID列时,合并csv文件中的许多数据帧吗?

    R - "Browser()"出现错误?

    r - 将 MASS::fitdistr 按一个因子应用于多个数据

    r - 仅用水平线绘制阶跃函数

    r - 一个图表中的条形图和线图,在 ggplot2 下带有图例

    r - 如何更改ggtern中长轴标题的位置?

    R:在编写文本文件时好看的列名称

    javascript - R Shiny HTML UI 无法正常工作

    r - 使用 coord_flip() 的 ggplot2 条形图中的图例条目顺序

    r - geom_point 图例颜色具有倒置的形状覆盖而不是实际形状