trama gganimate dove i punti rimangono e la linea si dissolve


11

Ecco un esempio riproducibile di un grafico statico, che voglio animare (voglio mostrare come si comporta un campionatore 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()

inserisci qui la descrizione dell'immagine

Quello che mi piacerebbe vedere è che i punti sono visibili quando vengono disegnati e un po 'sbiaditi (cioè l'alfa passa da ad esempio 1 a 0,3) in seguito, mentre ci sarebbe una linea che mostra solo la storia recente (e idealmente svanisce mostrando il la storia più recente la meno sbiadita e più di qualche passo indietro scompare totalmente).

Quanto segue raggiunge più o meno ciò che desidero per i miei punti (quindi in un certo senso voglio solo aggiungere linee di dissolvenza a questo collegamento degli ultimi punti - i punti che si dissolvono più lentamente su alcuni fotogrammi sarebbero ancora più belli):

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

Trama che mostra come i punti dovrebbero svanire

Ciò con cui sto lottando è come aggiungere due comportamenti diversi per due geomi, ad esempio punto e linea. Ad esempio, in basso i punti scompaiono (non li voglio) e le linee non si sbiadiscono (lo voglio).

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) 

Risposte:


17

Ho avuto problemi ad usare le shadow_*funzioni integrate per controllare più di un comportamento alla volta; sembrava applicare solo il più recente. (Usando gganimate 1.0.3.9000)

Un modo per aggirare il problema è calcolare manualmente le transizioni. Ad esempio, potremmo copiare i dati 100 volte, una copia per ciascun fotogramma e quindi specificare l'alfa per il nostro livello punti e l'alfa per il nostro livello segmento separatamente.

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)

inserisci qui la descrizione dell'immagine

(Per questo rendering, l'ho avvolto animate( [everything above], width = 600, height = 400, type = "cairo"))


1
Grazie mille. Un problema minore nella tua risposta: point_alpha = ... & segment_alpha = ... deve essere all'interno della mutazione (...). Modificata la risposta di conseguenza.
Björn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.