gganimate Handlung, in der Punkte bleiben und Linie verblasst

11

Hier ist ein reproduzierbares Beispiel eines statischen Diagramms, das ich animieren möchte (ich möchte zeigen, wie sich ein MCMC-Sampler verhält).

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()

Geben Sie hier die Bildbeschreibung ein

Was ich sehen möchte, ist, dass die Punkte sichtbar sind, wenn sie gezeichnet und danach etwas verblasst werden (dh Alpha geht von z. B. 1 auf 0,3), während es eine Linie gibt, die nur die jüngste Geschichte zeigt (und im Idealfall verblasst, um die zu zeigen) jüngste Geschichte am wenigsten verblasst und mehr als ein paar Schritte zurück völlig verschwunden).

Das Folgende erreicht mehr oder weniger das, was ich für meine Punkte möchte (in gewissem Sinne möchte ich nur verblassende Linien zu dieser Verbindung der letzten Punkte hinzufügen - Punkte, die über einige Frames langsamer verblassen, wären sogar noch schöner):

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

Diagramm, das zeigt, wie Punkte verblassen sollen

Ich habe Probleme damit, zwei verschiedene Verhaltensweisen für zwei Geome hinzuzufügen, z. B. Punkt und Linie. ZB unten verschwinden die Punkte (ich möchte nicht, dass sie es tun) und die Linien verblassen nicht (ich möchte, dass sie es tun).

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
quelle

Antworten:

17

Ich hatte Probleme, die integrierten shadow_*Funktionen zu verwenden, um mehr als ein Verhalten gleichzeitig zu steuern. es schien nur das neueste anzuwenden. (Mit gganimate 1.0.3.9000)

Eine Möglichkeit, dies zu umgehen, besteht darin, die Übergänge manuell zu berechnen. Zum Beispiel könnten wir die Daten 100 Mal kopieren, eine Kopie für jeden Frame, und dann das Alpha für unsere Punktebene und das Alpha für unsere Segmentebene separat angeben.

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)

Geben Sie hier die Bildbeschreibung ein

(Für diesen Render habe ich ihn eingewickelt animate( [everything above], width = 600, height = 400, type = "cairo"))

Jon Spring
quelle
1
Vielen Dank. Ein kleines Problem in Ihrer Antwort: point_alpha = ... & segment_alpha = ... muss sich innerhalb des Mutaten befinden (...). Die Antwort wurde entsprechend geändert.
Björn