在grid.layout中使用grid.layout与grid包:绘图顺序的奇怪影响

时间:2014-11-24 13:00:58

标签: r viewport r-grid

我想在堆叠的矩形内部绘制一些带有基本图形的图像。

enter image description here

我有一个绘图功能来生成带有堆积图(这里是矩形)的图:

stackedplot <- function(main=""){

  top.vp <- viewport(
    layout=grid.layout(5, 2,
                       widths=unit(c(2, 1), c("lines", "null")),
                       heights=unit(c(3, 1, 1, 1, 5), 
                                    c("lines", "null", "null", "null", "lines"))))
  p1 <- viewport(layout.pos.col=2, layout.pos.row=2, name="plot1",
                 default.units="native")
  p2 <- viewport(layout.pos.col=2, layout.pos.row=3, name="plot2",
                 default.units="native")
  p3 <- viewport(layout.pos.col=2, layout.pos.row=4, name="plot3",
                 default.units="native")
  xaxis <- viewport(layout.pos.col=2, layout.pos.row=5, name="xaxis")
  label1 <- viewport(layout.pos.col=1, layout.pos.row=2, name="label1")
  label2 <- viewport(layout.pos.col=1, layout.pos.row=3, name="label2")
  label3 <- viewport(layout.pos.col=1, layout.pos.row=4, name="label3")
  title <- viewport(layout.pos.col=2, layout.pos.row=1, name="title")

  splot <- vpTree(top.vp, vpList(p1,p2,p3,xaxis,label1,label2,label3,title))
  pushViewport(splot)

  seekViewport("plot1")
  # par(plt=gridPLT()) # Needed for plotting base graphics, but not here
  grid.rect(width=unit(0.9, "npc")) # This to be replaced with a base graphics plot in the final version

  seekViewport("plot2")
  # par(plt=gridPLT())
  grid.rect(width=unit(0.9, "npc"))

  seekViewport("plot3")
  # par(plt=gridPLT())
  grid.rect(width=unit(0.9, "npc"))

  seekViewport("xaxis")
  grid.text("X label", y = unit(3, "lines"))

  seekViewport("label1")
  grid.text("1", x = unit(2, "lines"), rot=90)
  seekViewport("label2")
  grid.text("2", x = unit(2, "lines"), rot=90)
  seekViewport("label3")
  grid.text("3", x = unit(2, "lines"), rot=90)

  seekViewport("title")
  grid.text(main, y = unit(1, "lines"), gp = gpar(fontsize = 20))
}

为了创建一个带有四个堆积图的2x2网格,我尝试使用以下代码:

grid.newpage()
multitop.vp <- viewport(layout=grid.layout(2,2))
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B")
pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C")
pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D")
vpall <- vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4))
pushViewport(vpall)
seekViewport("A")
stackedplot(main="A")
seekViewport("B")
stackedplot(main="B")
seekViewport("C")
stackedplot(main="C")
seekViewport("D")
stackedplot(main="D")

这不起作用,因为所有绘图都绘制在网格的同一单元格中。

enter image description here

然而,如果我以相反的顺序绘制它们,我会得到我想要的数字(第一个数字)。

seekViewport("D")
stackedplot(main="D")
seekViewport("C")
stackedplot(main="C")
seekViewport("B")
stackedplot(main="B")
seekViewport("A")
stackedplot(main="A")

我尝试了不同的名字并发现,如果我按逆向字母顺序绘图,一切正常。一旦我尝试在字母顺序中以较早的名称绘制视口,之后所有其他绘图都绘制在同一单元格中。为什么会这样?

1 个答案:

答案 0 :(得分:0)

在网格包的作者的一些帮助下,我现在回答我自己的问题,以防它对其他人有用。

我的代码创建了一个视口层次结构,其中视口plot1和plot2多次出现。在这种情况下使用seekViewport函数会出现问题。它始终从根开始搜索请求的视口。然后它下降并找到第一个plot1,它是viewport A下面的一个。因此,更好的选择是使用函数upViewport和downViewport,如下面的代码所示。

stackedplot <- function(main=""){

  top.vp <- viewport(
    layout=grid.layout(5, 2,
                       widths=unit(c(2, 1), c("lines", "null")),
                       heights=unit(c(3, 1, 1, 1, 5), 
                                    c("lines", "null", "null", "null", "lines"))))
  p1 <- viewport(layout.pos.col=2, layout.pos.row=2, name="plot1",
                 default.units="native")
  p2 <- viewport(layout.pos.col=2, layout.pos.row=3, name="plot2",
                 default.units="native")
  p3 <- viewport(layout.pos.col=2, layout.pos.row=4, name="plot3",
                 default.units="native")
  xaxis <- viewport(layout.pos.col=2, layout.pos.row=5, name="xaxis")
  label1 <- viewport(layout.pos.col=1, layout.pos.row=2, name="label1")
  label2 <- viewport(layout.pos.col=1, layout.pos.row=3, name="label2")
  label3 <- viewport(layout.pos.col=1, layout.pos.row=4, name="label3")
  title <- viewport(layout.pos.col=2, layout.pos.row=1, name="title")

  splot <- vpTree(top.vp, vpList(p1,p2,p3,xaxis,label1,label2,label3,title))
  pushViewport(splot)

  upViewport()
  downViewport("plot1")
  grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc"))

  upViewport()
  downViewport("plot2")
  grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc"))

  upViewport()
  downViewport("plot3")
  grid.rect(width=unit(0.9, "npc"), height=unit(0.9, "npc"))  

  upViewport()
  downViewport("xaxis")
  grid.text("X label", y = unit(3, "lines"))

  upViewport()
  downViewport("label1")
  grid.text("1", x = unit(2, "lines"), rot=90)

  upViewport()
  downViewport("label2")
  grid.text("2", x = unit(2, "lines"), rot=90)

  upViewport()
  downViewport("label3")
  grid.text("3", x = unit(2, "lines"), rot=90)


  upViewport()
  downViewport("title")
  grid.text(main, y = unit(1, "lines"), gp = gpar(fontsize = 20))

  upViewport(2)
}


grid.newpage()
multitop.vp <- viewport(layout=grid.layout(2,2))
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
pl2 <- viewport(layout.pos.col=1, layout.pos.row=2, name="B")
pl3 <- viewport(layout.pos.col=2, layout.pos.row=1, name="C")
pl4 <- viewport(layout.pos.col=2, layout.pos.row=2, name="D")
vpall <- vpTree(multitop.vp, vpList(pl1,pl2,pl3,pl4))
pushViewport(vpall)
upViewport()
downViewport("A")
stackedplot(main="A")
upViewport()
downViewport("B")
stackedplot(main="B")
upViewport()
downViewport("C")
stackedplot(main="C")
upViewport()
downViewport("D")
stackedplot(main="D")
upViewport(2)