#r #gganimate
#r #gganimate
Вопрос:
У меня простой график:
sample_data <-
data.frame(
x = 1:100
, y = 1:100
)
temp_plot <-
ggplot(sample_data
, aes(x = x
, y = y))
geom_line(
size = 3
, arrow = arrow()
, lineend = "round"
, linejoin = "round"
)
theme_minimal()
это выглядит так:
И я хочу анимировать его gganimate
примерно так:
temp_animate <-
temp_plot
transition_reveal(x)
anim_save("temp_animate.gif"
, temp_animate
, "~/Downloads/"
, end_pause = 10)
Однако, когда я это делаю, стрелка указывает неправильное направление вплоть до самого последнего кадра (приостановлено, чтобы было ясно, что в этот момент оно правильное).
Я пробовал играть со значениями arrow
(включая различные углы, включая отрицательные), но ничто из того, что я делаю, похоже, не исправляет ориентацию стрелки (которая должна указывать вдоль текущего вектора в каждом кадре).
Как я могу заставить стрелку указывать в правильном направлении повсюду? (Я размещаю это как проблему в каталоге github).
Комментарии:
1. Я думаю, что в вашем примере может отсутствовать одна или две строки кода, потому что я не вижу, как
temp_plot
становитсяtemp_animate
где угодно…2. Спасибо, @Z.Lin. Я пропустил это, когда копировал вставку. Это просто добавление
transition_reveal(x)
, и теперь это вопрос.
Ответ №1:
Объяснение
Это явление возникает из transition_reveal
-за того, что значения tweens для получения позиции перехода (где находится наконечник стрелки) в каждом кадре. Всякий раз, когда вычисленная позиция перехода совпадает с фактической точкой в наборе данных, для одного и того же местоположения будет два набора координат. Это приводит к обратной стрелке.
(В вашем примере стрелка полностью перевернута, потому что количество кадров по умолчанию совпадает с количеством строк в ваших данных, поэтому каждая вычисленная позиция перехода является дубликатом существующей точки данных. Если номер кадра равен какому-либо другому числу, например, 137, стрелка в одних кадрах будет меняться в обратном направлении, а в других — указывать прямо.)
Мы можем продемонстрировать это явление с меньшим набором данных:
p <- ggplot(data.frame(x = 1:4, y = 1:4),
aes(x, y))
geom_line(size = 3, arrow = arrow(), lineend = "round", linejoin = "round")
theme_minimal()
transition_reveal(x)
animate(p ggtitle("4 frames"), nframes = 4, fps = 1) # arrow remains reversed till the end
animate(p ggtitle("10 frames"), nframes = 10, fps = 1) # arrow flips back amp; forth throughout
Обходной путь
Ключевая функция здесь expand_data
взята из объекта TransitionReveal
ggproto . Я написал модифицированную версию, которая добавляет проверку на наличие дублированных позиций перед возвратом расширенного набора данных:
TransitionReveal2 <- ggproto(
"TransitionReveal2", TransitionReveal,
expand_panel = function (self, data, type, id, match, ease, enter, exit, params,
layer_index) {
row_vars <- self$get_row_vars(data)
if (is.null(row_vars))
return(data)
data$group <- paste0(row_vars$before, row_vars$after)
time <- as.numeric(row_vars$along)
all_frames <- switch(type,
point = tweenr:::tween_along(data, ease, params$nframes,
!!time, group, c(1, params$nframes),
FALSE, params$keep_last),
path = tweenr:::tween_along(data, ease, params$nframes,
!!time, group, c(1, params$nframes),
TRUE, params$keep_last),
polygon = tweenr:::tween_along(data, ease, params$nframes,
!!time, group, c(1, params$nframes),
TRUE, params$keep_last),
stop(type, " layers not currently supported by transition_reveal",
call. = FALSE))
all_frames$group <- paste0(all_frames$group, "<", all_frames$.frame, ">")
all_frames$.frame <- NULL
# added step to filter out transition rows with duplicated positions
all_frames <- all_frames %>%
filter(!(.phase == "transition" amp;
abs(x - lag(x)) <= sqrt(.Machine$double.eps) amp;
abs(y - lag(y)) <= sqrt(.Machine$double.eps)))
all_frames
}
)
Мы можем определить альтернативную версию transition_reveal
, которая использует вышеуказанное вместо:
transition_reveal2 <- function (along, range = NULL, keep_last = TRUE) {
along_quo <- enquo(along)
gganimate:::require_quo(along_quo, "along")
ggproto(NULL, TransitionReveal2, # instead of TransitionReveal
params = list(along_quo = along_quo, range = range, keep_last = keep_last))
}
Продемонстрируйте исходные данные:
temp_plot transition_reveal2(x)
Комментарии:
1. Мне все еще непонятно, почему стрелка меняется на противоположную, когда есть повторяющиеся координаты, но достаточно знать, что это так . Я дам ссылку на ваш ответ по вопросу Github, который я открыл. Возможно, они смогут включить вашу версию
transition_reveal
в следующее обновление. Спасибо!2. Причина разворота стрелки мне тоже не ясна, но на данный момент это
grid
скорее проблема, чемgganimate
проблема, и я действительно недостаточно сделал, чтобы понять первое. = P