如何对齐多个ggplot2图并在所有图上添加阴影 [英] How to align multiple ggplot2 plots and add shadows over all of them

查看:235
本文介绍了如何对齐多个ggplot2图并在所有图上添加阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

,但没有运气 - 我甚至无法安装尖端软件包;

  • 最后,我尝试了 gtable解决方案使用以下代码:

      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)




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



    有人可以在这里帮我一下吗?

    解决方案

    您可以使用基本绘图功能来实现这个特定的绘图。

     #设置对齐方式为拖曳阴谋。需要额外的零来获得底部轴的空间。 
    layout(矩阵(c(0,1,2,0),ncol = 1),高度= c(1,3,3,1))

    #绘制空间(0表示底部和顶部)
    par(mar = c(0,5,0,5))

    #1。绘制
    图(df $ V2〜df $ TIME2,type =l,xlim = c(1000,2000),axes = F,ylab =)

    #两个矩形 - y坐标较大以确保所有空间都被占用
    rect(1100,-15000,1300,15000,col =red,border =red)
    rect(1800,-15000,

    #再次绘制同一条线(用矩形显示线条)
    par(new = TRUE)
    plot(df $ V2〜df $ TIME2,type =l,xlim = c(1000,2000),axes = F,ylab =)

    #设定轴
    (1,at = seq(800,2200,200),labels = NA)
    轴(4,at = seq(-15000,10000,5000),las = 2)


    #绘图2相同。ylim =中的rev()确保反转轴。
    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, (df $($))= $ d $ $变量1〜df $ TIME1,type =l,ylim = rev(范围(df $ VARIABLE1)+ c(-0.1,0.1)),xlim = c(1000,2000),axes = F,ylab =)
    轴(1,at = seq(800,2200,200))
    轴(2,at = seq(-6.4,-8.4,-0.4),las = 2)



    更新 - 解决方案与ggplot2



    首先,创建两个新的数据框,其中包含矩形的信息。

    数据帧(xmin = 1800,xmax = 1300,ymin = -Inf,ymax = Inf)
    rect2 < - 数据帧(xmin = 1800,xmax = 1850, ymin = -Inf,ymax = Inf)

    修改原始绘图代码 - 移动 data aes geo m_line(),然后添加两个 geom_rect()调用。最重要的部分是 plot.margin = theme()中。对于每个绘图,我将其中一个边距设置为 -1 行(对于 p1 >和 > p2 ) - 这将确保情节将加入。所有其他利润率应该是相同的。对于 p2 也删除轴刻度。

     库(ggplot2)
    库(网格)
    库(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),alpha = 0.1,fill =blue)+
    geom_rect(data = rect2,aes(xmin = xmin,xmax = xmax,ymin = ymin,ymax = ymax) )+
    主题(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 (limit = 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 xis.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)


    Please download the data here!

    Target: Plot an image like this:

    Features: 1. two different time series; 2. the lower panel has a reverse y-axis; 3. shadows over two plots.

    Possible solutions:
    1. Facetting is not appropriate - (1) can not just make one facet's y axis reverse while keep the other(s) unchanges. (2) difficult to adjust the individual facets one by one.
    2. Using viewports to arrange individual plots using the following codes:

    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))
    

    Problems:

    1. the x-axis doesn't align correctly;
    2. the shadow locations are wrong (because of the incorrect line-up of x-axis).

    After Googling all around:

    1. I firstly noticed that "align.plots() from ggExtra" could do this job. However, it has been deprecated by the author;
    2. Then I've tried the gglayout solution, but no luck - I even could not install the "cutting-edge" package;
    3. Finally, I've tried the gtable solution using the following code:

      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)
      

    Now, the x-axis of upper and lower panel do align correctly. But the shadow positions are still wrong. And more importantly, I can not overlap the shadow plot on the two time-series. After several day's attempts, I nearly give up...

    Could somebody here give me a hand?

    解决方案

    You can achieve this particular plot also using just base plotting functions.

    #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)
    

    UPDATE - Solution with ggplot2

    First, make two new data frames that contain information for rectangles.

    rect1<- data.frame (xmin=1100, xmax=1300, ymin=-Inf, ymax=Inf)
    rect2 <- data.frame (xmin=1800, xmax=1850, ymin=-Inf, ymax=Inf)
    

    Modified your original plot code - moved data and aes to inside geom_line(), then added two geom_rect() calls. Most essential part is plot.margin= in theme(). For each plot I set one of margins to -1 line (upper for p1 and bottom for p2) - that will ensure that plot will join. All other margins should be the same. For p2 also removed axis ticks. Then put both plots together.

    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)
    

    这篇关于如何对齐多个ggplot2图并在所有图上添加阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆