Juraj
Juraj

Reputation: 99

Ggplot - plot a dataframe with multiple points in 1 row in order to animate it with gganimate

I have a dataframe where each row contains information about the coordinates of 8 points at a point in time:

Time x1 y1 x2 y2 x3 y3 … x8 y8

A row may look like this for example:

myData <- data.frame(time=0.1,x1=-7.79,y1=7.32,x2=-3.86,y2=-1.62,x3=-1.35,y3=-4.61,x4=-6.24,y4=-9.89,x5=-6.40,y5=2.00,x6=4.02,y6=4.77,x7=-1.42,y7=9.89,x8=6.59,y8=-8.02)

The problem I have is that ggplot only accepts 1 column name for each axis. Moreover, I would like to animate the movements of the points using gganimate, that's why I want to use ggplot. How can I do this?

I managed to animate the data by drawing a plot using the standard R plot() method for each point in time and redrawing it, but that doesn't allow me to save the animation or work with it further.

Upvotes: 0

Views: 669

Answers (2)

PavoDive
PavoDive

Reputation: 6496

I'm just getting used to tidyr and the pipe operator, so I'll appreciate any suggestions for improving this answer:

You first need to reshape your data (as @Heroka suggested), and then to split the axis and points (they're mingled in the x1, y8 names), so you'll end with a properly shaped data frame that you can pass to ggplot:

gather(myData, "coord", "value", -time) %>% 
  separate(coord, sep = 1, into = c("axis", "val2")) %>% 
  spread(key = axis, value = value) %>% 
  ggplot(aes(x = x, y = y)) + geom_point()

I'm not familiar with gganimate, but am pretty sure that form here you can find your path...

EDIT:

You can identify each point if you change the last line of code to:

ggplot(aes(x = x, y = y, color = val2)) + geom_point()

EDIT 2:

Following @Sitbu's suggestion, I changed the first line of code

Upvotes: 1

Stibu
Stibu

Reputation: 15907

This builds on the answer by PavoDive and just adds how the animation part is done.

I define a larger data set such that there actually is something to animate:

set.seed(1544)
myData <- data.frame(seq(0, 1, by = 0.1),
                     matrix(runif(11*8*2, -10, 10), nrow = 11))
names(myData) <- c("time", paste0(c("x", "y"), rep(1:8, each = 2)))

and then I use PavoDive's code to convert to long format:

library(tidyr)
library(magrittr)
long_data <- 
gather(myData, "coord", "value", -time) %>% 
  separate(coord, sep = 1, into = c("axis", "val2")) %>% 
  spread(key = axis, value = value)

Using gg_animate() is luckily rather simple. All you have to do is add a frame aesthetic:

p <- ggplot(long_data, aes(x = x, y = y, frame = time)) + geom_point()
gg_animate(p, "animation.gif")

enter image description here

If you are using RStudio, you can omit the file name in gg_animate() to show the plot in RStudio's plot pane.

Upvotes: 1

Related Questions