сюжет, где остаются точки и линии исчезают

11

Вот воспроизводимый пример статического графика, который я хочу анимировать (я хочу показать, как ведет себя сэмплер MCMC).

library(tidyverse)
library(gganimate)

set.seed(1234)
plot_data <- tibble(x=cumsum(rnorm(100)),
                    y=cumsum(rnorm(100)),
                    time=1:length(x)) 

ggplot(data=plot_data,
       aes(x=y, y=x)) +
  geom_point() + geom_line()

введите описание изображения здесь

То, что я хотел бы видеть, это то, что точки видны, когда они нарисованы и немного потускнели (т.е. альфа переходит, например, от 1 до 0,3) после этого, тогда как была бы линия, которая показывает только недавнюю историю (и в идеале исчезает, показывая Самая недавняя история наименее поблекла и более чем на несколько шагов назад полностью исчезла).

Следующее дает более или менее то, что я хочу для своих точек (поэтому, в некотором смысле, я просто хочу добавить линии затухания к этому соединению последних нескольких точек - точки, которые затухают медленнее в некоторых кадрах, будут еще лучше):

ggplot(data=plot_data,
       aes(x=y, y=x)) +
  geom_point() +
  transition_time(time) +
  shadow_mark(past = T, future=F, alpha=0.3)

График, показывающий, как точки должны исчезать

Я борюсь с тем, как добавить два разных поведения для двух геомов, например, точки и линии. Например, в приведенных ниже точках исчезают (я не хочу их) и линии не исчезают (я хочу их).

p <- ggplot(data=plot_data,
       aes(x=y, y=x)) +
  geom_point() +
  transition_time(time) +
  shadow_mark(past = T, future=F, alpha=0.3)

p + geom_line() +
  transition_reveal(along = time) +
  shadow_mark(past = T, future=F, alpha=0.3) 
Бьерн
источник

Ответы:

17

У меня были проблемы с использованием встроенных shadow_*функций для управления более чем одним поведением одновременно; казалось, просто применить самый последний. (Использование gganimate 1.0.3.9000)

Один из способов обойти это - рассчитать переходы вручную. Например, мы могли бы скопировать данные 100 раз, по одной копии на каждый кадр, а затем указать альфа для нашего слоя точек и альфа для нашего слоя сегмента отдельно.

plot_data %>%
  uncount(100, .id = "frame") %>%
  filter(time <= frame) %>%
  arrange(frame, time) %>%
  group_by(frame) %>%
  mutate(x_lag = lag(x), 
         y_lag = lag(y),
         tail = last(time) - time,
         # Make the points solid for 1 frame then alpha 0.3
         point_alpha = if_else(tail == 0, 1, 0.3),
         # Make the lines fade out over 20 frames
         segment_alpha = pmax(0, (20-tail)/20)) %>%
  ungroup() %>%

  ggplot(aes(x=y, y=x, xend = y_lag, yend = x_lag, group = time)) +
  geom_segment(aes(alpha = segment_alpha)) +
  geom_point(aes(alpha = point_alpha)) +
  scale_alpha(range = c(0,1)) +
  guides(alpha = F) +
  transition_manual(frame)

введите описание изображения здесь

(Для этого рендера я его завернул animate( [everything above], width = 600, height = 400, type = "cairo"))

Джон Спринг
источник
1
Большое спасибо. Одна небольшая проблема в вашем ответе: point_alpha = ... & сегмент_alpha = ... должен быть внутри мутата (...). Изменил ответ соответственно.
Бьорн