ggplot2 中 geom_circle 的动画显示无意的插值圆

问题描述 投票:0回答:1

我用

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
    

非常感谢您解决问题的建议。

r ggplot2 animation gif
1个回答
0
投票

实现此目的的最简单方法是使用时间列将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

© www.soinside.com 2019 - 2024. All rights reserved.