2014-06-22 131 views
1

我想用ggplot2創建某種動畫,但它不起作用,因爲我想。這是一個簡單的例子。動畫,添加幾何

print(p <- qplot(c(1, 2),c(1, 1))+geom_point()) 
print(p <- p + geom_point(aes(c(1, 2),c(2, 2))) 
print(p <- p + geom_point(aes(c(1, 2),c(3, 3))) 

手動添加額外的點是沒有問題的。但現在我想在一些循環中獲得動畫。

for(i in 4:10){ 
    Sys.sleep(.3) 
    print(p <- p + geom_point(aes(c(1,),c(i, i)))) 
} 

但是現在僅顯示添加的新點,並且刪除了先前迭代的點。我希望舊的仍然可見。我怎樣才能做到這一點?

回答

1

其中任何一個都可以做你想做的,我想。

# create df dynamically 
for (i in 1:10) { 
    df <- data.frame(x=rep(1:2,i),y=rep(1:i,each=2)) 
    Sys.sleep(0.3) 
    print(ggplot(df, aes(x,y))+geom_point() + ylim(0,10)) 
} 

# create df at the beginning, then subset in the loop 
df <- data.frame(x=rep(1:2,10), y=rep(1:10,each=2)) 
for (i in 1:10) { 
    Sys.sleep(0.3) 
    print(ggplot(df[1:(2*i),], aes(x,y))+geom_point() +ylim(0,10)) 
} 

此外,您的代碼將導致y軸限制爲每個圖改變。使用ylim(...)可以保持所有圖形的尺寸相同。

編輯對OP評論的迴應。

創建動畫的一種方法是使用animations包。這是一個例子。

library(ggplot2) 
library(animation) 
ani.record(reset = TRUE) # clear history before recording 
df <- data.frame(x=rep(1:2,10), y=rep(1:10,each=2)) 
for (i in 1:10) { 
    plot(ggplot(df[1:(2*i),], aes(x,y))+geom_point() +ylim(0,10)) 
    ani.record() # record the current frame 
} 
## now we can replay it, with an appropriate pause between frames 
oopts = ani.options(interval = 0.5) 
ani.replay() 

這將「記錄」的每個幀(使用ani.record(...)),然後回放在使用ani.replay(...)結束。閱讀documentation瞭解更多詳情。

關於爲什麼你的代碼失敗的問題,簡單的答案是:「這不是ggplot設計使用的方式。」更復雜的答案是:ggplot基於一個框架,該框架期望您將默認數據集標識爲數據框,然後將圖(美學)的各個方面與數據框中的列相關聯(映射)。所以,如果你有列AB數據幀df,並要繪製BA,你可以這樣寫:

ggplot(data=df, aes(x=A, y=B)) + geom_point() 

該代碼標識df的數據集,以及審美X映射(中橫軸)列A,y列B。考慮的參數的默認順序的好處,你也可以這樣寫:

ggplot(df, aes(A,B)) + geom_point() 

它可以指定aes(...)比列名的其他東西,但這樣可以而且經常會導致意外(甚至怪異)的結果。 不要這樣做!

的原因,基本上是ggplot沒有立即的參數計算爲aes(...),而是將它們存儲在一個ggplot object表情,當你繪製或打印對象對其進行評估。這就是爲什麼,例如,您可以將圖層添加到繪圖,並且ggplot可以動態地重新縮放x和y限制,這與基底R中的plot(...)不起作用。

+0

非常感謝。很有幫助。但是,爲什麼我的示例工作,如果我手動添加點,而不是在for循環?有沒有辦法做到不閃爍?也許還有其他一些用於liveplots的工具? – Kulibo

+0

查看我上面的編輯。 – jlhoward

+0

再次感謝您。非常有啓發性。我會嘗試使用動畫包。乾杯 – Kulibo