【问题标题】:Ggplot - plot a dataframe with multiple points in 1 row in order to animate it with gganimateGgplot - 在 1 行中绘制具有多个点的数据框,以便使用 gganimate 对其进行动画处理
【发布时间】:2016-06-09 16:40:19
【问题描述】:

我有一个数据框,其中每一行都包含有关某个时间点 8 个点的坐标的信息:

时间 x1 y1 x2 y2 x3 y3 … x8 y8

例如,一行可能如下所示:

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)

我遇到的问题是 ggplot 每个轴只接受 1 个列名。此外,我想使用 gganimate 为点的运动设置动画,这就是我想使用 ggplot 的原因。我该怎么做?

我设法通过使用标准 R plot() 方法为每个时间点绘制绘图并重新绘制它来为数据设置动画,但这不允许我保存动画或进一步使用它。

【问题讨论】:

  • 你能做一个可重现的例子吗?查看this,我的方法是融合您的数据(可能必须使用 data.table 来做到这一点,因为它接受两个测量变量。然后您可以添加frame = Time
  • @Heroka 我在问题中添加了一个数据框示例。我真的无法添加更多代码,因为我不知道如何让 ggplot 做我想做的事。
  • ggplot 需要长格式的数据。第一步试试这个:library(data.table); m_dat &lt;- melt(setDT(myData), id.var="Time",measure.vars=patterns(c("x","y")), value.names=c("x","y"))
  • Juraj - 请展示您的尝试。我建议像 Herka 那样融化你的数据框。在去 ggplot2 之前,我使用库 tidyr 和 dplyr。 blog.rstudio.org/2014/07/22/introducing-tidyr
  • 谢谢@Heroka,你的方法奏效了:)

标签: r ggplot2 gganimate


【解决方案1】:

这建立在 PavoDive 的答案之上,只是添加了动画部分的完成方式。

我定义了一个更大的数据集,以便实际上有一些动画:

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

然后我使用 PavoDive 的代码转换为长格式:

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

幸运的是,使用gg_animate() 相当简单。您所要做的就是添加框架美感:

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

如果您使用的是 RStudio,您可以省略 gg_animate() 中的文件名以在 RStudio 的绘图窗格中显示绘图。

【讨论】:

  • 我从来不需要动画情节,所以我认为gganimate 相当复杂。这很简单!可能会派上用场的一件事是固定轴限制,因此查看器实际上可以实现每个时间步的每个点的移动。
  • 它非常简单。所以我们都学到了一些东西!关于您的评论:轴保持不变。假设您将time 映射到colour 而不是frame。然后,ggplot() 将选择坐标轴,以便所有颜色的点都显示在图中。将time 映射到frame 时也是如此。您可以通过如下修改long_data 来尝试:long_data[long_data$time == 0.5, "x"] &lt;- 0。 x 轴范围在所有帧中仍然相同。还是很简单!
【解决方案2】:

我刚刚习惯了tidyr 和管道操作员,所以我会感谢任何改进这个答案的建议:

您首先需要重塑您的数据(如@Heroka 建议的那样),然后拆分轴和点(它们混合在 x1、y8 名称中),因此您将以正确形状的数据框结束你可以传递给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()

我不熟悉gganimate,但我很确定您可以在这里找到您的路径...

编辑:

如果将最后一行代码更改为:

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

编辑 2:

根据@Sitbu 的建议,我更改了第一行代码

【讨论】:

  • 太棒了!我不知道separate()...只有一个建议:在第一行,你可以写gather(myData, "coord", "value", -time),这样更清楚,不管有多少列都一样。
猜你喜欢
  • 2019-07-26
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多