Анимация, добавление геома
Я хочу создать какую-то анимацию с 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(...)
сохраняет все участки в одном масштабе.
РЕДАКТИРОВАТЬ Ответ на комментарий ОП.
Одним из способов создания анимации является использование 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(...)
, Прочитайте документацию для более подробной информации.
Что касается вопроса о том, почему ваш код не работает, простой ответ: "это не тот способ, которым ggplot предназначен для использования". Более сложный ответ таков: ggplot
основан на платформе, которая ожидает, что вы определите набор данных по умолчанию в качестве фрейма данных, а затем свяжете (отобразите) различные аспекты графа (эстетика) со столбцами в фрейме данных. Так что если у вас есть фрейм данных df
с колоннами A
а также B
и вы хотите построить B
против A
, вы бы написали:
ggplot(data=df, aes(x=A, y=B)) + geom_point()
Этот код идентифицирует df
в качестве набора данных и отображает эстетический х (горизонтальная ось) с колонкой A
и у с колонкой B
, Воспользовавшись порядком аргументов по умолчанию, вы также можете написать:
ggplot(df, aes(A,B)) + geom_point()
Можно указать вещи, отличные от имен столбцов в aes(...)
но это может и часто приводит к неожиданным (даже странным) результатам. Не делай этого!,
Причина в основном в том, что ggplot
не оценивает аргументы aes(...)
немедленно, а скорее сохраняет их как выражения в ggplot object
и оценивает их при печати или печати этого объекта. Вот почему, например, вы можете добавить слои на график, а ggplot может динамически изменять масштаб по x- и y-пределам, что не работает с plot(...)
в базе Р.