gigantyczna fabuła, w której pozostają punkty i zanika linia

11

Oto odtwarzalny przykład wykresu statycznego, który chcę animować (chcę pokazać, jak zachowuje się sampler 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()

wprowadź opis zdjęcia tutaj

To, co chciałbym zobaczyć, to punkty widoczne po ich narysowaniu, a następnie nieco wyblakłe (tj. Alfa zmienia się z np. 1 na 0,3), podczas gdy byłaby linia, która pokazuje tylko najnowszą historię (i idealnie zanika pokazując najnowsza historia najmniej wyblakła i więcej niż kilka kroków wstecz całkowicie zniknęła).

Następujące osiąga mniej więcej to, co chcę dla moich punktów (więc w pewnym sensie chcę po prostu dodać linie zanikające do tego połączenia ostatnich kilku punktów - punkty zanikające wolniej w niektórych ramkach byłyby jeszcze ładniejsze):

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

Wykres pokazujący, jak punkty powinny zanikać

Mam problem z dodaniem dwóch różnych zachowań dla dwóch geom, np. Punktu i linii. Np. Poniżej punkty znikają (nie chcę ich), a linie nie znikają (chcę, żeby).

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) 
Björn
źródło

Odpowiedzi:

17

Miałem problem z używaniem wbudowanych shadow_*funkcji do kontrolowania więcej niż jednego zachowania na raz; wydawało się, że po prostu stosuje najnowszą. (Korzystanie z gganimate 1.0.3.9000)

Jednym ze sposobów obejścia tego jest ręczne obliczenie przejść. Na przykład możemy skopiować dane 100 razy, po jednej kopii dla każdej klatki, a następnie osobno określić alfa dla naszej warstwy punktów i alfa dla naszej warstwy segmentu.

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)

wprowadź opis zdjęcia tutaj

(W tym renderowaniu owinąłem go animate( [everything above], width = 600, height = 400, type = "cairo"))

Jon Spring
źródło
1
Dziękuję Ci bardzo. Jeden drobny problem w twojej odpowiedzi: point_alpha = ... & segment_alpha = ... muszą znajdować się w mutate (...). Odpowiednio zmodyfikowałem odpowiedź.
Björn