带knitr的动态rgl图
我想通过带knitr的动态rgl图,r,animation,knitr,rgl,rnw,R,Animation,Knitr,Rgl,Rnw,我想通过knitr在我的.Rnw文档中包含动画rgl图形。这是我的MWE: \documentclass{article} << label = setup, include = FALSE>>= opts_chunk$set(fig.path = 'figure/', cache = FALSE, dev = "pdf", fig.align = 'center', fig.show = 'hold', fig.width = 3, fig.height = 3,
knitr
在我的.Rnw
文档中包含动画rgl
图形。这是我的MWE:
\documentclass{article}
<< label = setup, include = FALSE>>=
opts_chunk$set(fig.path = 'figure/', cache = FALSE, dev = "pdf", fig.align = 'center', fig.show = 'hold', fig.width = 3, fig.height = 3, echo = TRUE, warning = FALSE, message = FALSE, size = 'footnotesize', comment=NA, results='hold')
knit_hooks$set(par = function(before, options, envir){
if (before && options$fig.show!='none')
par(mar = c(4, 4, 0.1, 0.1), cex.lab = 0.95, cex.axis = 0.9, mgp = c(2, 0.7, 0), tcl = -0.3)
}
)
knit_hooks$set(rgl = function(before, options, envir) {
if (!before) {
## after a chunk has been evaluated
if (rgl.cur() == 0) return() # no active device
name = paste(options$fig.path, options$label, sep = '')
rgl.snapshot(paste(name, '.png', sep = ''), fmt = 'png')
return(paste('\\includegraphics{', name, '}\n', sep = ''))
}
}
)
options(replace.assign = TRUE, width = 60)
@
\begin{document}
<< label=packages >>=
library(car)
@
<< label=rgl1, rgl=TRUE, fig.show='animate' >>=
scatter3d(prestige ~ income + education, data=Duncan)
@
\end{document}
我的sessionInfo()
是
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] tools stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] mgcv_1.8-2 nlme_3.1-117 rgl_0.93.1098 car_2.0-21 knitr_1.6.15
loaded via a namespace (and not attached):
[1] evaluate_0.5.5 formatR_1.0 grid_3.1.1 highr_0.3
[5] lattice_0.20-29 MASS_7.3-34 Matrix_1.1-4 nnet_7.3-8
[9] stringr_0.6.2
已编辑
将
opts_chunk$set
中的fig.path='figure/'
更改为fig.path='
,将使用png
图形编译文档,但不带任何动画。如何使用fig.path='figure/'
获得动画的rgl
图形我有一个基于您的示例,它在RStudio 0.99.441的Windows 8.1上使用knitr
这将生成情节的40帧动画。它使用内置的hook\u plot\u custom
来包含通过设置3d绘图动画手动生成的绘图。动画的代码基于play3d
和movie3d
的帮助和来源中的代码movied3d
本身无法使用,因为它的文件命名过于死板
我已经在github上发布了这个。pdf在
此示例在我的环境中非常有效。在
Pixmap save
错误中引用的文件名看起来非常奇怪。你的工作目录是什么?感谢@BenBolker对我的问题感兴趣。我的工作目录是D:\A B\C D UAF\Test\knitr\rglAnimation
。我强烈建议您尝试一个路径名中没有空格的工作目录。这在文档中可能没有明确禁止,并且可能在包代码级别上是可以修复的,但是这种情况经常会破坏依赖于系统调用的R代码。您是对的@BenBolker。即使从工作目录的名称中删除空格也不起作用。谢谢@NickK的出色回答。在我的机器上,fig.path='figure/'
不起作用,因此我必须将fig.path='figure/'
更改为fig.path='
。你知道这段代码将如何用于fig.path='figure/'
。如果您能告诉我Adobe Reader播放动画,我将不胜感激。ThanksI不得不手动创建“figure”子文件夹,之后工作正常。你能确认你是否已经有一个同名的文件夹吗?如果没有,则使用您喜欢的任何方式创建一个(dir.create(“figure”)
)。我也会尝试使用png(“figure/test.png”);地块(1);dev.off()
。我使用Windows上的Adobe Reader席(当前版本)和AcROTAT X也在Windows上。它在苏门答腊岛(RStudio中的PDF阅读器)或我尝试过的任何iOS PDF阅读器(包括Adobe自己的)上都不会动画。通过将生成的PNG通过ffmpeg生成一个.mp4文件,然后使用media9嵌入它,可以生成一个在Okular和Adobe reader上都能工作的动画。但是我不认为knitr直接支持这个功能,所以它需要更多的编码。理论上,iOS上的ezPDFreader也会支持这一点,尽管我没有测试它。我在RStudio PDF viewer中运行第一个示例,它会显示一些动画大约1秒,然后我在par3d中得到Error:chunk 2(label=rgl1)Error(windowRect=100+opts_current$get(“dpi”)*c(0,0,opts_current$get(“fig.width”),:参数“windowRect”的执行暂停了错误的长度
@akhmed您确定没有错误的内容吗?您可以省略该行,它仍然可以工作,但会小于设置的大小。
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] tools stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] mgcv_1.8-2 nlme_3.1-117 rgl_0.93.1098 car_2.0-21 knitr_1.6.15
loaded via a namespace (and not attached):
[1] evaluate_0.5.5 formatR_1.0 grid_3.1.1 highr_0.3
[5] lattice_0.20-29 MASS_7.3-34 Matrix_1.1-4 nnet_7.3-8
[9] stringr_0.6.2
\documentclass{article}
\usepackage{animate}
<< label = setup, include = FALSE>>=
library("rgl")
library("car")
library("knitr")
knit_hooks$set(rgl = hook_plot_custom)
@
\begin{document}
<< label=rgl1, rgl=TRUE, fig.show='animate', fig.width=5, fig.height=5, out.width='.6\\linewidth', dev='png', fig.num = 40, interval=0.1>>=
scatter3d(prestige ~ income + education, data=Duncan)
M <- par3d("userMatrix")
par3d(windowRect = 100 + opts_current$get("dpi") *
c(0, 0, opts_current$get("fig.width"),
opts_current$get("fig.height")))
spinFunc <- par3dinterp(userMatrix=list(M,
rotate3d(M, pi/2, 1, 0, 0),
rotate3d(M, pi/2, 0, 1, 0)))
for(i in 1:40) {
par3d(spinFunc(i / 10))
Sys.sleep(0.05)
rgl.snapshot(fig_path(".png", number = i), fmt = "png")
}
@
\end{document}
\documentclass{article}
\usepackage{animate}
<< label = setup, include = FALSE>>=
library("rgl")
library("car")
library("knitr")
hook_rgl_spin <- function(before, options, envir) {
if (!before) {
par3d(windowRect = 100 + options$dpi *
c(0, 0, options$fig.width,
options$fig.height))
if (!is.null(options$spin3d.axis)) {
spin3d.axis <- options$spin3d.axis
} else {
spin3d.axis <- c(0, 0, 1)
}
if (!is.null(options$spin3d.rpm)) {
spin3d.rpm <- options$spin3d.rpm
} else {
spin3d.rpm <- c(0, 0, 1)
}
spinFunc <- spin3d(axis = spin3d.axis, rpm = spin3d.rpm)
for(i in 1:options$fig.num) {
par3d(spinFunc(i * options$interval))
Sys.sleep(0.05)
rgl.snapshot(fig_path(".png", number = i), fmt = "png")
}
hook_plot_custom(before, options, envir)
}
}
knit_hooks$set(rgl = hook_rgl_spin)
@
\begin{document}
<< label=rgl1, rgl=TRUE, fig.show='animate', fig.width=5, fig.height=5, out.width='.6\\linewidth', dev='png', fig.num = 40, interval=0.1, spin3d.axis=c(0, 0, 1), spin3d.rpm = 20>>=
scatter3d(prestige ~ income + education, data=Duncan)
@
\end{document}