1

我只是在尝试我的第一步grid。作为练习,我想创建一个pairs()完全基于grid. 下面的函数myplotGrob应该创建网格对象(grob;或 gTree)并返回该对象。

我不确定继续的最佳方式是什么。应该使用哪些单位?(也试过"null") 是frameGrob为了设置布局吗?(这是我从 Paul Murrell 的书中了解到的)我如何选择/调整视口以便获得所需的情节(到目前为止,我只看到一团糟)布局是要预先设置的还是它更好地逐步“连接”附加面板以获得 (4, 4) 绘图矩阵?

require(grid)
require(mvtnorm)

set.seed(271)
X <- rmvnorm(1000, mean=1:4, sigma=diag(4:1)) # goal: draw this in a pairs plot

## auxiliary function
panel <- function(x, y) pointsGrob(x=x, y=y, name="panel", gp=gpar(), vp=NULL)

## creates and returns a gTree (class)
myplotGrob <- function(X, name=NULL, gp=NULL, vp=NULL)
{
    ## x-axis grob

    ## y-axis grob

    ## ...

    ## set up layout
    layout <- grid.layout(4, 4, # (4, 4) matrix
                          widths=rep(0.25, 4), heights=rep(0.25, 4),
                          default.units="npc")
    ## pushViewport(viewport(layout=layout)) # required???

    all <- frameGrob(layout=layout) # produces a gTree without children
    for(i in 1:4) {
        for(j in 1:4) {
            ## group grobs together
            gt <- gTree(X,
                        children=gList(panel(X[,i], X[,j])),
                        name=name, gp=gp, vp=vp, cl="myplotGrob")
            all <- placeGrob(all, gt, row=i, col=j)
        }
    }
    all
}

## draw the gTree
grid.myplot <- function(...) grid.draw(myplotGrob(...))

## call
grid.myplot(X)

更新

正如所要求的那样,这是我想到的原始问题的设计/布局(上面只是一个最小的/学习示例)。以厘米为单位的单位只适合我(它们最终应该是“相对的”)。当然,面板的数量可能会有所不同。我希望所有部分都是网格对象,以便创建图形的函数将返回一个对象(不打印/绘图)。这样,每个部分都可以在之后进行修改。图形应显示维度为 5(或更小)的数组的结果:一个维度显示在行面板 [ row.vars] 中,一个维度显示在列面板 [ ] 中,一个维度显示在col.vars每个面板的 x 轴 [ xvar] 中,每个面板可以包含 2 个不同维度的数组(因颜色和线型而异)[我使用dn图中]。如果当然,如果数组是四维的,那么上面设计的第 8 行应该是缺失的。我可以通过网格构建布局,但整个问题是如何从那里继续。这就是我想用上面的“最小示例”来表达的。

在此处输入图像描述

4

2 回答 2

2

我认为您可以将任务分为两个主要部分,例如和中的基本grid.panel()示例grid.multipanel()

1-构建一个将生成单个面板的函数,以 gTree 形式返回。您需要弄清楚所有参数,即限制、轴、颜色、形状、网格、坐标……您最终可能会重写格子面板函数和轴,

grid.newpage()
grid::grid.panel(vp=viewport(width=0.8, height=0.8))

在此处输入图像描述

2- 在布局中组装面板。使用gtable容易(也更干净),

library(gtable)

grid.newpage()
lg <- replicate(16, grobTree(rectGrob(), pointsGrob()), simplify=FALSE)

gt <- gtable_matrix("pairs", grobs=matrix(lg, ncol=4),
                    widths=unit(rep(1, 4), "null"),
                    heights=unit(rep(1, 4), "null"))

gt <- gtable_add_col_space(gt, width=unit(0.5,"line"))
gt <- gtable_add_row_space(gt, height=unit(0.5,"line"))
gt <- gtable_add_padding(gt, padding=unit(1,"line"))

grid.draw(gt)

如果你想从头开始构建所有东西,我认为你最终也将不得不重新发明 gtable 的很大一部分。

在此处输入图像描述

于 2013-07-28T22:54:09.360 回答
1

这是一个类似于grid.multipanel()但返回 gTree 的尝试,更具体到您的配对图,

require(grid)
require(mvtnorm)

set.seed(271)
X <- rmvnorm(100, mean=1:4, sigma=diag(4:1)) # goal: draw this in a pairs plot

panelGrob <- function(x=runif(10, -10, 10), y=runif(10, -10, 100), ...,
  xlim = range(x), ylim=range(y),
  axis.x=TRUE, axis.y=TRUE){
  xx <- pretty(x) ; yy <- pretty(y)
  xx <- xx[xx <= xlim[2] & xx >= xlim[1]]
  yy <- yy[yy <= ylim[2] & yy >= ylim[1]]

  r <- rectGrob()
  dvp <- dataViewport(xData=xx, yData=yy)
  p <- pointsGrob(x, y, pch=".", gp=gpar(col="red"), default.units="native",
                  vp = dvp)

  ax <- if(axis.x) xaxisGrob(at=xx, vp=dvp) else nullGrob()
  ay <- if(axis.y) yaxisGrob(at=yy, vp=dvp) else nullGrob()

  grobTree(r, ax, ay, p, ...)
}

grid.panel <- function(...)
  grid.draw(panelGrob(...))

grid.newpage()
grid.panel(vp=viewport(width=0.8, height=0.8))


pairsGrob <- function(X, ..., name=NULL, gp=NULL, vp=NULL){

  N <- NCOL(X)
  layout <- grid.layout(N+1, N+1, 
                        widths=unit(c(2, rep(1, N)), c("lines", rep("null", N))), 
                        heights = unit(c(rep(1, N), 2), c(rep("null", N), "lines")))


  wrap <- function(ii, jj, ...){
    panelGrob(X[,ii], X[,jj], ..., axis.x= ii == N, axis.y = jj == 1,
              vp=viewport(layout.pos.row=ii, layout.pos.col=jj+1))
  }

  rowcol <- expand.grid(ii=seq_len(N), jj=seq_len(N))
  gl <- mapply(wrap, ii=rowcol[,"ii"], jj=rowcol[,"jj"], MoreArgs=list(...),
               SIMPLIFY=FALSE)

  gTree(children=do.call(gList, gl), vp=viewport(layout=layout))
}

grid.pairs <- function(...) grid.draw(pairsGrob(...))

grid.newpage()
grid.pairs(X, xlim=c(-10,10), ylim=c(-10,10))

在此处输入图像描述

许多问题已经很明显了:i) 在布局中添加间距、跟踪正确的视口很麻烦;ii) 面板功能的大多数参数都是硬连线的(点形状、颜色、网格、轴标签……),为复杂性的爆炸做好准备,如args(lattice::panel.xyplot); iii)轴的范围应该在一行/列中匹配,这需要考虑将数据正确分组(ggplot2或lattice中的分面);iv) 传说是在网格中重塑的另一件事;五)...

于 2013-07-28T22:57:02.340 回答