从一个图形到另一个图形的平滑通道

时间:2015-05-23 03:25:36

标签: r graphics graph

考虑以下两个图

require(ggplot2)
set.seed(5276)
my_mtcars = mtcars
my_mtcars$rand = rnorm(nrow(mtcars))

ggplot(my_mtcars, aes(rand, mpg)) + geom_point()

enter image description here

ggplot(my_mtcars, aes(wt, mpg)) + geom_point()

enter image description here

我想制作一部电影(或任何可以很容易地在.ppt中引入的动画图片),从第一张图片到第二张图片顺利通过。在通过期间,我们会看到点平滑地水平移动到达目的地。 x轴刻度和标签也应该出现(最终顺利)。

我会尝试创建许多作为中间图片的.png,然后使用ImageMagick(Bash)制作一个gif,但我很确定应该有更好的解决方案。我使用ggplot2来制作情节,但我并不严格。这是我目前尝试的内容

IntFormat = function(x,nbdigits=0){
  cx = paste0(x)
  l = length(strsplit(cx,"")[[1]])
  if (nbdigits < l){nbdigits = l; print("WARNING: Parameter `nbdigits` too small")}
  before = paste(rep("0",nbdigits-l), collapse="")
  paste0(before, cx)
}

SmoothGraph = function(x1, x2, y1, y2, times = "NOTSET", ...){
    path = "/Users/remi/Desktop/"
    if (times == "NOTSET") {
        times = c(seq(0,0.1,length.out=10), seq(0,0.2, length.out=5), seq(0.2,0.8, length.out=6), seq(0.8,0.9, length.out=5), seq(0.9,1,length.out=10))
    }
    nbdigits = length(times)
    count = 0
    x1_rel = x1 / (max(x1) - min(x1))
    x1_rel = x1_rel - max(x1_rel) + 1
    x2_rel = x2 / (max(x2) - min(x2))
    x2_rel = x2_rel - max(x2_rel) + 1
    y1_rel = y1 / (max(y1) - min(y1)) - min(y1)
    y1_rel = y1_rel - max(y1_rel) + 1
    y2_rel = y2 / (max(y2) - min(y2)) - min(y2)
    y2_rel = y2_rel - max(y2_rel) + 1
    x_diff = x2_rel - x1_rel
    y_diff = y2_rel - y1_rel
    for (time in times){
        count = count + 1
        xtmp = x1_rel + x_diff * time
        ytmp = y1_rel + y_diff * time
        print(count)
        png(paste0(path, "SmoothGraph_", IntFormat(count, nbdigits=nbdigits), ".png"))
        plot(x=xtmp, y=ytmp, ...)
        dev.off()
    }
    system (command="
    cd /Users/remi/Desktop/
    convert SmoothGraph_*.png -delay 1 SmoothGraph.gif
    rm SmoothGraph_*.png
    ")
}

SmoothGraph(x1=rnorm(12), y1=mtcars$mpg , x2 = mtcars$wt, y2=mtcars$mpg)

1 个答案:

答案 0 :(得分:2)

这似乎非常适合animation包。你可以这样做。首先,定义一个可以在两个图之间进行插值的函数

framedata<-function(x) {
    subset(transform(my_mtcars, 
        x=rand + x*(wt-rand),
        y=mpg
    ), select=c(x,y))
}

然后你可以用

为它们制作动画
library(animation)
frame <- seq(0, 1, length.out=20)
saveGIF(lapply(frame, function(f) {
    print( ggplot(framedata(f), aes(x, y)) + geom_point() )
}), "go.gif", interval = 0.05, loop=1)

这将创建一个20帧动画,在播放一次的帧之间延迟.05秒。