сюжет, где остаются точки и линии исчезают - PullRequest
9 голосов
/ 07 октября 2019

Вот воспроизводимый пример статического графика, который я хочу анимировать (я хочу показать, как ведет себя сэмплер 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()

enter image description here

То, что я хотел бы видеть, это то, что точки видны, когда они нарисованы и немного потускнели (т.е. альфа идет от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)

Plot showing how points should fade

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

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) 

1 Ответ

14 голосов
/ 11 октября 2019

У меня были проблемы с использованием встроенных функций 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)

enter image description here

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

...