thomasp85 / gganimate

A Grammar of Animated Graphics
https://gganimate.com
Other
1.94k stars 308 forks source link

Animating a network graph with transition_manual - any way to make a subset of nodes remain visible throughout the animation? #471

Closed Tsode closed 1 year ago

Tsode commented 1 year ago

Hi, thank you very much for the fantastic package! I was wondering if there was any way to get a subset of data points to remain visible throughout the animation using transition_manual or other transition commands? I have created a network image using igraph, ggnetwork and ggplot so I could animate it with gganimate, and I'd like the central nodes and their labels to remain visible throughout the animation, but the surrounding nodes to change from frame to frame. The data is observations of groups of people from different city parts, and I'd like the city part nodes to remain visible throughout and the observations to change. I haven't figured out how to use for instance shadow_mark or transition_layers to achieve this.

Here are some details:

A mock dataset mimcking my original:

nodeid<-c(5:16, 1,2,3,4)
place<-c(rep("", times=12), "A", "B", "C", "D")
place_num<-c(1,1,1,2,2,2,3,3,3,4,4,4,1,2,3,4)
type<-c(1,2,3,3,2,3,1,2,2,2,1,1,4,4,4,4)
size<-c(1,4,3,2,1,1,3,3,5,3,2,2,1,1,1,1)
timecat<-c(9,10,11,9,9,10,10,11,11,9,10,11,9,9,9,9)
nodes<-data.frame(nodeid, place, place_num, type, size, timecat)
edges1<-subset(nodes, select=c(place_num, nodeid)
edges<-edges1[1:16,]

And the code I used to create the network image:

net<-graph_from_data_frame(edges, directed=F, vertices=nodes)

ptime<-ggplot(
 ggnetwork(net,
 layout = with_fr(),
 ),
 aes(x, y, xend = xend, yend = yend)
 ) +
 geom_edges(color="grey50")+
 geom_nodes(aes(color = type, size=size)) +
 scale_color_brewer("type",
 palette = "Paired") +
 theme_blank()+
 geom_nodes(aes(color = type, size=size)+
 geom_nodetext(label=nodes$place)
  )

And the animation:

ptime2<-ptime+transition_manual(timecat)+labs(title = "City, time: {current_frame}")

All this works really nicely but I can't figure out how to have the "place" nodes (nodeids 1-4) remain in all the frames and have the other nodes change (of course now I have told transitionmanual to only show them in the first, "9" timecat frame because I had to enter some value there). Is there any transition* subcommand that could achieve this?

Tsode commented 1 year ago

Sorry, after posting I discovered transition_events, which seems to work perfectly!