我用
gifski
包中的R
创建了一个GIF动画。
这是输入和输出数据(抱歉我不知道是否可以通过在线存储服务共享)。
https://drive.google.com/drive/folders/1Zj2tXBKrfNfM3ezi4hKF8He4CVYImT4L?usp=sharing
这是动画中使用的原始地图。
在动画(test.gif)中,您可以看到一个圆心设置在底部的固定红点,其大小(半径)跟随移动蓝点之间的距离。
该圆的信息存储在
circle_df.rds
中,仅包含13秒(行),而存储在gps.rds
中的蓝点信息包含大约700秒。我期望的结果是,仅当时间帧到达 circle_df
中存储的时间时才显示这些圆圈,但是,当前动画从数据帧的第一个到末尾连续显示圆圈,其中圆圈大小被插值。
这是繁殖脚本。
## Google maps API
register_google(key="YOURKEY", write=TRUE)
## Extract satellite image from google maps
map <- ggmap(get_googlemap(center=cor, zoom=18, maptype="satellite"))
## Plot map
p <- map +
geom_point(data=gps, aes(x=lon, y=lat),
color="blue", size=2, shape=10) +
geom_point(data=sensor, aes(x=lon, y=lat),
color="red", fill="white", size=3.4, shape=21) +
# Add labels at the center of each point
geom_text(data=sensor, aes(x=lon, y=lat, label=ID),
color="red", fontface="bold", size=2.4, vjust=0.24) +
## Circle from sensor
geom_circle(data=circle_df, aes(x0=lon, y0=lat,
color=signal, r=as.numeric(distance_deg)),
fill=NA, alpha=0.6, linewidth=0.8) +
scale_color_gradient(low="dodgerblue", high="red",
name=expression("Signal Intensity\n(-100 to 0)"),
# breaks=seq(-100, 0, by=10), limits=c(-100,0),
guide = guide_colorbar(title.theme=element_text(color="white", size=10),
label.theme = element_text(color = "white", size=10),
barwidth=1, barheight = 5, nbin = 10)) +
## Theme
theme(axis.title.x=element_blank(),
axis.text.x = element_blank(),
axis.title.y=element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
rect = element_blank(),
legend.position=c(0.9,0.14),
plot.margin = unit(c(0, 0, 0, 0), "cm")) +
## Animation
## Variable to animate
transition_time(time) +
## Title
ggtitle('Time:, {frame_time}',
subtitle = 'Frame {frame} of {nframes}') # +
## Add slider
# slider::slidify(gps$time, time_range=range(gps$time))
## Animate
## Number of frames
frame <- as.integer((max(gps$time) - min(gps$time)) * 60)
## Plot
anime <- animate(p, nframes=frame, fps=round(frame/20))
# Change x in frame/x based on duration of animation (x)
## Save
anim_save("test.gif", anime) ; anime
非常感谢您解决问题的建议。
实现此目的的最简单方法是使用时间列将circle_df 连接到 gps df 来创建新的 df。这样,您就可以在没有圆圈的每一秒获得 NA,因此这些秒在动画中变为空白。请注意,您会收到警告:
警告信息: 删除了包含非有限值的 687 行 (stat_circle()
)。
这只是引用 df 中的 NA 行,可以忽略。我没有 API 密钥,但其他一切都一样。
library(dplyr)
library(ggforce)
library(gganimate)
gps <- readRDS("C:/test/gps.rds")
circle_df <- readRDS("C:/test/circle_df.rds")
sensor<- readRDS("C:/test/sensor.rds")
# Join circle_df to gps
df <- gps %>%
left_join(., circle_df, by = "time")
p <- ggplot() +
geom_point(data=gps, aes(x=lon, y=lat),
color="blue", size=2, shape=10) +
geom_point(data=sensor, aes(x=lon, y=lat),
color="red", fill="white", size=3.4, shape=21) +
# Add labels at the center of each point
geom_text(data=sensor, aes(x=lon, y=lat, label=ID),
color="red", fontface="bold", size=2.4, vjust=0.24) +
## Circle from sensor
geom_circle(data=df, aes(x0=lon.y, y0=lat.y,
color=signal, r=as.numeric(distance_deg)),
fill=NA, alpha=0.6, linewidth=0.8) +
scale_color_gradient(low="dodgerblue", high="red",
name=expression("Signal Intensity\n(-100 to 0)"),
# breaks=seq(-100, 0, by=10), limits=c(-100,0),
guide = guide_colorbar(title.theme=element_text(color="white", size=10),
label.theme = element_text(color = "white", size=10),
barwidth=1, barheight = 5, nbin = 10)) +
## Theme
theme(axis.title.x=element_blank(),
axis.text.x = element_blank(),
axis.title.y=element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
rect = element_blank(),
legend.position=c(0.9,0.14),
plot.margin = unit(c(0, 0, 0, 0), "cm")) +
## Animation
## Variable to animate
transition_time(time) +
## Title
ggtitle('Time:, {frame_time}',
subtitle = 'Frame {frame} of {nframes}') # +
## Add slider
# slider::slidify(gps$time, time_range=range(gps$time))
## Animate
## Number of frames
frame <- as.integer((max(gps$time) - min(gps$time)) * 60)
## Plot
anime <- animate(p, nframes=frame, fps=round(frame/20))
# Change x in frame/x based on duration of animation (x)
## Save
anim_save("test.gif", anime) ; anime