在R中制作动态彗星图

8
有没有R中的库或函数可以简化彗星图的制作?我指的是一个动画图,其中头部(箭头)跟踪粒子的路径,它的身体(线条)跟着头部后面,长度与粒子的速度成比例。 Matlab有一个非常简单的comet()函数,文档在这里:http://www.mathworks.co.uk/help/matlab/ref/comet.html 一个非常好的展示当前风速的彗星图的实例在这里:http://earth.nullschool.net/ 我意识到这是一个非常普遍的问题,但我在R中还没有找到任何内容。

我认为R语言没有类似的东西。也许可以考虑JavaScript或jQuery? - Roman Luštrik
1
这可以使用 D3.js 完成,可以在 D3.js 网站上查看示例。 - Paul Hiemstra
2个回答

15

这个加上动画效果怎么样?

# required libraries
require(animation) # NB you must install ImageMagick
require(ggplot2)
require(grid) # for arrow()

# create a path with variable speed (1 point per time unit)
path<-data.frame(time=1:100,x=1:100,y=c((1:50)^2,(50:1)^2))
# plot it, just to see
ggplot(path)+geom_point(aes(x,y))

在此输入图片描述

# work out the path and previous points of each observation
# average of previous 2 steps, but could be any number
steps<-2
path$prevx<-c(rep(0,steps),path$x[1:(nrow(path)-steps)])
path$prevy<-c(rep(0,steps),path$y[1:(nrow(path)-steps)])
path$prevtime<-c(rep(0,steps),path$time[1:(nrow(path)-steps)])
# then calculate the velocity at each point, and the angle (for the arrow)
# note we could just plot point to point, but that assumes the time units are regular
path$v<-((((path$x-path$prevx)^2)+((path$y-path$prevy)^2))^0.5)/(path$time-path$prevtime)
path$atan2<-atan2((path$x-path$prevx),(path$y-path$prevy))

# OK, we now have all the data; let's plot first without animation
ggplot(path)+geom_segment(aes(x = x-(v*sin(atan2)), y = y-(v*cos(atan2)), xend = x, yend = y),
                          arrow=arrow(length = unit(0.5, "cm")) ,
                          alpha=0.5, size=2,
                          color="blue")

在此输入图片描述

# create function which takes a vector of rows (to plot a subset of arrows)
plot_arrow<-function(vec){
  alphas<-rev(1/(1:length(vec))^1.5) # this create an alpha scale
  g<-ggplot(path[vec,])+geom_segment(aes(x = x-(v*sin(atan2)), y = y-(v*cos(atan2)), xend = x, yend = y),
                               arrow=arrow(length = unit(0.5, "cm")) , # create arrow
                               alpha=alphas, size=2,
                               color="blue")+
    coord_cartesian(xlim=c(min(path$x),max(path$x)),ylim=c(min(path$y),max(path$y))) # fix width
  print(g)
}

# then create the animated GIF with 5 arrows per frame
saveGIF({
  lapply(1:nrow(path),function(x)plot_arrow(max(1,x-5):x))
},movie.name="comet.gif",interval=0.2)

enter image description here

PS: 您还可以通过更改plot_arrow()函数调用(在'geom_segment'中的arrow()调用)来删除尾部箭头:

arrow=arrow(length = unit(c(rep(0,length(vec)-1),0.5), "cm"))

这里输入图片描述


9
你可以使用优秀的animation包进行操作。
也许你应该将points调用更改为线段(或同时调用它们),但这应该是一个不错的开始。

图片描述

library(animation)
saveGIF({
  ani.options(interval = 0.2, nmax = 10)
  t = seq(0,2*pi,.01)
  x = cos(2*t)*(cos(t)^2)
  y = sin(2*t)*(sin(t)^2)
  idx = seq(1,length(x),10)
  for (i in seq_along(idx)) {
    plot(x,y,type='n')
    points(x[seq(idx[i])],y[seq(idx[i])],pch=20,col='red')
    ani.pause()  ## pause for a while ('interval')
  }
}, interval = 0.05, movie.name = "comet_demo.gif", 
        outdir = "/usr/temp",ani.width = 600, ani.height = 600)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接