在R中的rgl包中将f输入play3d()和movie3d()

Input f into play3d() and movie3d() in the rgl package in R

我不明白 rgl 包中 play3d 和 movie3d 期望的输入 f。

library(rgl)

nobs<-10
x<-runif(nobs)
y<-runif(nobs)
z<-runif(nobs)
n<-rep(1:nobs)
df<-as.data.frame(cbind(x,y,z,n))
listofobs<-split(df,n)

plot3d(df[,1],df[,2],df[,3], type = "n", radius = .2 )

myplotfunction<-function(x) {
  rgl.spheres(x=x$x,y=x$y,z=x$z, type="s", r=0.025)
}

当执行下面的两行时,动画会播放,但是这两行(play3d() 和 movie3d())都会触发下面显示的错误:

play3d(f=lapply(listofobs,myplotfunction), fps=1 )
movie3d(f=lapply(listofobs,myplotfunction), fps=1 , duration=20)

我希望有人可以更正我的代码并帮助我理解 play3d 和 movie3d 的 f 输入。

问题 1:为什么上面的 play3d 行足够正确以至于动画可以正确显示?

问题 2:为什么上面的 play3d 行不正确以至于触发错误?

问题3:movie3d线不产生视频输出是什么问题?

正如文档所说,f 是“一个返回可能传递给 par3d 的列表的函数”。不是列表,这是你的用法。

回答问题:

  1. R 评估执行动画的 lapply 调用,然后 play3d 查看结果并终止,因为它不是函数。
  2. f 需要是一个函数,如帮助页面中所述。
  3. 它在查看 f 时就死了,因为它不是一个函数。

这看起来会做你想做的事:

library(rgl)

nobs<-10
x<-runif(nobs)
y<-runif(nobs)
z<-runif(nobs)
df<-data.frame(x,y,z)

plot3d(df, type = "n" ) 
id <- NA
myplotfunction<-function(time) {
  index <- round(time)
  # For a 3x faster display, use index <- round(3*time)
  # To cycle through the points several times, use 
  # index <- round(3*time) %% nobs + 1
  if (!is.na(id))
    pop3d(id = id) # Delete previous item
  id <<- spheres3d(df[index,], r=0.025)
  list()
}

play3d(myplotfunction, startTime = 1, duration = nobs - 1)
movie3d(myplotfunction, startTime = 1, duration = nobs - 1, fps = 1)

这将在 file.path(tempdir(), "movie.gif") 中留下一个 GIF。

一些其他注意事项:

  • 不要打电话给 rgl.spheres。以后会给你带来巨大的痛苦。使用 spheres3d,或者 从不 调用任何 *3d 函数,并且从不升级 rgl:你生活在过去使用 rgl.* 职能。 *3d 函数和 rgl.* 函数不能很好地协同工作。
  • 构建dataframe,直接使用data.frame()函数即可,不要转换 一个矩阵。
  • 您不需要所有这些扭曲来从数据框中提取点。
  • 大多数 rgl 函数可以处理具有 xyz 列的数据帧。
  • 您可能会注意到 plot3d 框架移动了一点:球体比点大,因此它会调整以适应它们。如果您不喜欢这样,您可以使用 xlimylimzlim 将原始框架设置得更大一些。