在 R 中动画改变内核宽度的效果

机器算法验证 r 内核平滑
2022-03-02 06:19:34

我在 R 中有一些数据,存储在列表中。思考

d <- c(1,2,3,4) 

虽然这不是我的数据。如果我然后输入命令

 plot(density(d, kernel="gaussian", width=1))

然后我得到内核概率密度估计,其中内核是标准正态的。如果我用其他数字替换 1,图片当然会改变。

我想做的是创建一个视频或动画,其中每一帧都是这样的情节,但是内核的带宽因帧而异,从而显示出改变带宽的效果。我怎样才能做到这一点?

(如果这里不适合提问关于 R 的问题,我深表歉意。)

4个回答

这在一定程度上取决于您的最终目标是什么。

用于实时演示的快速而肮脏的 hack

Sys.sleep(seconds)在循环中使用seconds指示帧之间的秒数是一个可行的选择。您需要在调用中设置xlim和参数以使事情按预期运行。ylimplot

这是一些简单的演示代码。

# Just a quick test of Sys.sleep() animation

x <- seq(0,2*pi, by=0.01)
y <- sin(x)
n <- 5
pause <- 0.5

ybnds <- quantile(n*y, probs=c(0,1))
x11()

# Draw successively taller sinewaves with a gradually changing color
for( i in 1:n )
{
    plot(x, i*y, type="l", lwd=2, ylim=ybnds, col=topo.colors(2*n)[i])
    Sys.sleep(pause)
}

这很好用,尤其是使用 X-Windows 作为窗口系统。不幸的是,我发现 Mac 的quartz()播放效果不好。

动画 GIF

如果您需要可以重新分发、发布在网页上等的东西,请查看caTools包中的write.gif功能。显示帮助给出了几个很好的例子,包括几个动画——一个使用 Mandelbrot 集的很好的例子。write.gif

另请参阅此处此处

更精细的控制和更精美的动画

有一个看起来很强大的动画包。不过,我自己没有使用过它,所以我无法给出任何真正的建议。

已经看到了这个包的一些很好的输出示例,它们看起来很不错。也许其中一个“亮点”是在 PDF 中嵌入动画的能力。

一种方法是使用Yihui Xie 的优秀动画包。我将一个非常简单的示例上传到我的公共保管箱帐户:密度图(我将在 3 天内删除此示例)。这是你想要的?

动画是使用以下 R 代码创建的:

library(animation)
density.ani <- function(){
    i <- 1  
    d <- c(1,2,3,4) 
    while (i <= ani.options("nmax")) {
      plot(density(d, kernel="gaussian", bw = i), ylim = c(0, 0.25))
      ani.pause()
      i <- i + 1
    }
}

saveHTML({
par(mar = c(5, 4, 1, 0.5))
density.ani()
}, nmax = 30, title = "Changing kernel width")

只是为了完整起见,如果你需要这个来进行课堂演示,我还会提到RStudiomanipulate附带的包请注意,这个包依赖于 RStudio 接口,所以它不能在它之外工作。

manipulate非常酷,因为它允许快速创建一些滑块来操作图中的任何元素。这将允许在课堂上进行一些简单且实时的演示。

manipulate(
  plot(density(1:10, bw)),
  bw = slider(0, 10, step = 0.1, initial = 1)) 

这里的其他例子

这是另一种方法:

library(TeachingDemos)

d <- c(1,2,3,4)

tmpfun <- function(width=1, kernel='gaussian'){
    plot(density(d, width=width, kernel=kernel))
}

tmplst <- list( width=list('slider', init=1, from=.5, to=5, resolution=.1),
    kernel=list('radiobuttons', init='gaussian', values=c('gaussian',
        "epanechnikov","rectangular","triangular","biweight","cosine",
        "optcosine")))

tkexamp( tmpfun, tmplst, plotloc='left' )