Create breadcrumb-like trail using gganimate with hockey dataset

so-example

I've coded an animation on top of an ice hockey rink where I try to animate the location of ice hockey shots. The puck (black dot) appears on the spot where shot was taken, then next appears in the net. This process iterates itself for the entirety of the animation.

I'd like to create a "breadcrumb-like trail" so that I can animate the puck moving from shot location to the net. I've tried various shadow functions in gganimate , but can't figure out which shadow function / parameters to set.

Example dataset ( df ):

structure(list(event_index = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 
5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L, 11L, 11L, 12L, 
12L, 13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L, 17L, 18L, 18L, 
19L, 19L, 20L, 20L, 21L, 21L, 22L, 22L, 23L, 23L, 24L, 24L, 25L, 
25L, 26L, 26L, 27L, 27L, 28L, 28L, 29L, 29L, 30L, 30L, 31L, 31L, 
32L, 32L, 33L, 33L, 34L, 34L, 35L, 35L, 36L, 36L, 37L, 37L, 38L, 
38L, 39L, 39L, 40L, 40L, 41L, 41L, 42L, 42L, 43L, 43L, 44L, 44L, 
45L, 45L, 46L, 46L, 47L, 47L, 48L, 48L, 49L, 49L, 50L, 50L, 51L, 
51L, 52L, 52L, 53L, 53L, 54L, 54L, 55L, 55L, 56L, 56L), coords_x = c(80, 
82, 53, 82, 31, 82, -56, -82, -34, -82, -33, -82, -40, -82, 30, 
82, -66, -82, -36, -82, 45, 82, 17, 82, -6, 82, 47, 82, -51, 
-82, -31, -82, -69, -82, -86, -82, -70, -82, 80, 82, 65, 82, 
-76, -82, -71, -82, 81, 82, -57, -82, 80, 82, 75, 82, 77, 82, 
-71, -82, -40, -82, -83, -82, 62, 82, 77, 82, 76, 82, -61, -82, 
69, 82, -45, -82, 68, 82, 31, 82, 58, 82, 61, 82, 80, 82, 34, 
82, 80, 82, -85, -82, -37, -82, -57, -82, 76, 82, 14, 82, 49, 
82, -82, -82, -34, -82, -36, -82, -83, -82, -84, -82, -55, -82
), coords_y = c(-1, 0, 14, 0, -30, 0, 17, 0, 26, 0, -23, 0, -37, 
0, 17, 0, -32, 0, -18, 0, 25, 0, 17, 0, -38, 0, 21, 0, 28, 0, 
22, 0, 17, 0, 13, 0, 10, 0, -37, 0, -17, 0, 9, 0, 18, 0, -11, 
0, 21, 0, -7, 0, 3, 0, 3, 0, -38, 0, 31, 0, 8, 0, -30, 0, -2, 
0, 4, 0, -5, 0, 15, 0, 10, 0, -30, 0, -34, 0, 20, 0, 27, 0, -4, 
0, 8, 0, -18, 0, 19, 0, 32, 0, -21, 0, 0, 0, 40, 0, -4, 0, -30, 
0, -24, 0, -28, 0, -2, 0, -3, 0, 34, 0)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -112L))

Code to reproduce above animation:

rink <- rasterGrob(readJPEG("full-rink.jpg"), width=unit(1,"npc"), height=unit(1,"npc"))

anim <- df %>%
  mutate(event_time = seq_along(event_index)) %>%
  ggplot(aes(coords_x, coords_y, group = event_index)) +
  annotation_custom(rink, -100, 100, -45, 45) +
  geom_point(size = 2.5) +
  coord_fixed() +
  xlim(-100, 100) +
  ylim(-45, 45) +
  theme_void() +
  transition_time(event_time)

animate(anim, fps = 1)

Here is the rink image file:

See the shadow_*() family of functions (e.g. shadow_wake()).

https://gganimate.com/reference/index.html#section-shadows

2 Likes

Like I mentioned, I can't figure out which function + parameter from the shadow_*() family to use...maybe you could help out here?

The shadow_*() functions should work pretty well out of the box! I'd say start with shadow_trail() without any parameters (it seems like that's the one that'll give you the effect you're describing), and if you're not happy with it, try tuning the distance parameter. If it turns out it's not quite what you're looking for, give shadow_wake() a go. It'll be a little easier to help you if you can describe how it's not working for you :slight_smile:

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.