如何使用knitr中的网格逐步构建分层绘图?

时间:2013-07-06 10:33:06

标签: r knitr

对于讲习班附带的在线教程,我想强调网格包的使用(特别是如何使用视口)。为此,我想逐步构建一个图(即chunk chunk)。在每个步骤/块之间,我想包括一些普通文本,以便更详细地解释每个步骤。

如何告诉knitr不单独评估一个块,而是开始评估上一个块结束的位置?基本上,而不是我想要添加到前一个块的结果的块的新评估。

在下面的代码中,当编织为html时,我在.html输出中得到2个图。第一个显示第一个块的结果(粉红色矩形和一些文本),第二个显示第二个块的结果(蓝色矩形)。我想要实现的是两个图 - 第一个显示第一个块的结果(如上所示),第二个图显示第一个块的结果+第二个块的结果(粉红色矩形内的蓝色矩形) )。 基本上,我想在R控制台中运行时重现两个代码块的行为。蓝色矩形应放在粉红色矩形中,不能单独绘制。

这是第一个块

```{r grid first vp, tidy = FALSE}
library(grid)
grid.newpage()

## draw a rectangle around the root vp and provide some text
grid.rect()
grid.text("this is the root vp", x = 0.5, y = 1, just = c("centre", "top"))

vp <- viewport(x = 0.5, y = 0.5, 
               height = 0.5, width = 0.5,
               just = c("centre", "centre"))

pushViewport(vp)

grid.rect(gp = gpar(fill = "pink"))
grid.text("this is our first vp", x = 0.5, y = 1, just = c("centre", "top"))
```

之间有一些解释性文字:

“好的,现在我们在root视口中间创建了一个视口x = 0.5y = 0.5 - just = c("centre", "centre"),这是一半高度和一半原始视口的宽度 - height = 0.5width = 0.5

然后我们导航到这个视口 - pushViewport(vp),然后我们绘制了一个填充整个视口并用粉红色填充的矩形 - grid.rect(gp = gpar(fill = "pink"))

请注意,我们尚未离开视口。这意味着,无论我们现在做什么,都会在当前活动的视口(粉红色的视口)中发生。为了说明这一点,我们将再次重复上面完全相同的代码(我们只是要更改填充颜色,以便我们更好地看到更改)。“

这是第二块

```{r grid second vp, tidy = FALSE}

vp <- viewport(x = 0.5, y = 0.5, 
               height = 0.5, width = 0.5,
               just = c("centre", "centre"))

pushViewport(vp)

grid.rect(gp = gpar(fill = "cornflowerblue"))
```

我有什么想法告诉knitr'保留'以前的块中所做的一切,并将其作为当前块评估的“起点”?

2 个答案:

答案 0 :(得分:6)

没有记录,但这个功能已经存在了将近一年。要在整个编译过程中保持图形设备处于打开状态,您可以设置

opts_knit$set(global.device = TRUE)

我认为任何人都很少使用此功能,但似乎我错了。

答案 1 :(得分:0)

您可以使用grid.grab()捕获块末尾的场景,在新块中绘制它,然后导航到最后一个视口(需要命名)。不幸的是,knitr认为grid.grab()应该会产生新的情节,我不知道如何解决这个问题。

```{r first, tidy = FALSE}
library(grid)
grid.newpage()

## draw a rectangle around the root vp and provide some text
grid.rect()
grid.text("this is the root vp", x = 0.5, y = 1, just = c("centre", "top"))

vp <- viewport(x = 0.5, y = 0.5, 
               height = 0.5, width = 0.5,
               just = c("centre", "centre"), 
               name="first")

pushViewport(vp)

grid.rect(gp = gpar(fill = "pink"))
grid.text("this is our first vp", x = 0.5, y = 1, just = c("centre", "top"))
scene <- grid.grab()
```

```{r second, tidy = FALSE, fig.keep='last'}
grid.draw(scene)
seekViewport("first")
vp <- viewport(x = 0.5, y = 0.5, 
               height = 0.5, width = 0.5,
               just = c("centre", "centre"))

pushViewport(vp)

grid.rect(gp = gpar(fill = "cornflowerblue"))
```

当然,从实际的角度来看,re-run the code from the first chunk

要容易得多
```{r second, tidy = FALSE}
<<first>>
vp <- viewport(x = 0.5, y = 0.5, 
               height = 0.5, width = 0.5,
               just = c("centre", "centre"))

pushViewport(vp)

grid.rect(gp = gpar(fill = "cornflowerblue"))
```