在后续代码块中重用图形设备

时间:2014-09-19 10:28:07

标签: r graphics knitr

以下R-Markdown代码不适用于Knitr:

Create a bimodal toy distribution.

```{r}
a = c(rnorm(100, 5, 2), rnorm(100, 15, 3))
```

Set up the graphics device.

```{r fig.show='hide'}
plot(0, type = 'n', xlim = c(0, 20), ylim = c(0, 0.2), axes = FALSE)
```

Plot the density.

```{r}
polygon(density(a), col = 'black')
```

Knitr假设图形设备在R代码块的末尾结束,并关闭设备。因此,我不能重复使用(在第三个代码块中)先前设置的图形设备。

我的问题很简单:我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:3)

您可以通过recordPlot()保留以前的地图,并使用replayPlot()重绘。这可以在自定义块挂钩函数中完成。这是一个简单的例子:

```{r setup}
library(knitr)
knit_hooks$set(plot.reuse = local({
  last = NULL
  function(before, options) {
    if (!isTRUE(options$plot.reuse)) {
      last <<- NULL
      return(NULL)
    }
    if (before) {
      if (inherits(last, 'recordedplot')) replayPlot(last)
    } else {
      last <<- recordPlot()
    }
    return(NULL)
  }
}))
```

Draw a plot.

```{r test-a, plot.reuse=TRUE}
plot(cars)
```

Add a line to the previous plot:

```{r test-b, plot.reuse=TRUE}
abline(lm(dist~speed, data=cars))
```

您还可以使用未记录的功能opts_knit$set(global.device = TRUE),以便整个文档始终使用相同的图形设备,该设备永远不会关闭。我从未在公众中提到过这个功能,虽然已经存在了两年,因为我没有仔细考虑过这种方法可能产生的意外后果。

答案 1 :(得分:1)

这不是解决方案,而是一种解决方法:我正在使用ggplot,因此我能够在一个变量中存储一个图。由于变量是跨代码块共享的,因此可以在后续代码块中重复使用部分完整的对象。

答案 2 :(得分:-2)

根据我的理解,第一个图独立于第二个图。

```{r}
plot(0, type = 'n', xlim = c(0, 20), ylim = c(0, 0.2), axes = FALSE)
polygon(density(a), col = 'black')
```