如何让gganimate动画结束帧始终显示所有时间序列标签?
解决gganimate时间序列动画标签不全问题
问题核心:transition_reveal(Fecha2)会按时间逐步展示数据,geom_text默认只绘制当前帧中存在的行数据,导致只有最后一个时间点有记录的Metal(Zinc)显示标签。要全程显示所有标签,可通过以下两种方法解决:
方法一:用shadow_mark保留所有标签
直接给geom_text添加shadow_mark(),让已出现的标签保留在后续帧中:
library(ggplot2) library(gganimate) dt$Fecha2 <- as.Date(dt$Fecha, format = "%Y-%m-%d") s <- ggplot(data = dt, aes(x = Fecha2, y = Indice, color = Metal, label = Metal)) + geom_line() + geom_text(hjust = 1) + # 保留所有已出现的标签,不随帧推进消失 shadow_mark(past = TRUE, future = FALSE) + geom_vline(xintercept = as.numeric(as.Date("2020-03-16")), linetype = "dashed", colour = "red", size = 1) + theme(legend.position = "none") + scale_y_log10(breaks = c(75, 100, 125, 150, 175, 200)) + scale_x_date(date_breaks = "2 months", date_labels = "%d-%b-%y") + transition_reveal(Fecha2) animate(s, fps = 5, end_pause = 10)
方法二:预处理数据,确保每个时间点都有所有Metal的记录
先对数据做填充,让每个时间点都包含所有Metal的最新值,这样geom_text在每个帧都能绘制所有标签:
library(ggplot2) library(gganimate) library(dplyr) library(tidyr) dt$Fecha2 <- as.Date(dt$Fecha, format = "%Y-%m-%d") # 预处理:按Metal分组,填充每个时间点的最新Indice值,保证每个时间点都有所有Metal的记录 dt_filled <- dt %>% arrange(Fecha2) %>% group_by(Metal) %>% complete(Fecha2 = seq(min(dt$Fecha2), max(dt$Fecha2), by = "day")) %>% fill(Indice, .direction = "down") %>% ungroup() s <- ggplot(data = dt_filled, aes(x = Fecha2, y = Indice, color = Metal, label = Metal)) + geom_line() + # 每个时间点都显示所有Metal的末端标签 geom_text(data = dt_filled %>% group_by(Metal, Fecha2) %>% slice(n()), hjust = 1) + geom_vline(xintercept = as.numeric(as.Date("2020-03-16")), linetype = "dashed", colour = "red", size = 1) + theme(legend.position = "none") + scale_y_log10(breaks = c(75, 100, 125, 150, 175, 200)) + scale_x_date(date_breaks = "2 months", date_labels = "%d-%b-%y") + transition_reveal(Fecha2) animate(s, fps = 5, end_pause = 10)
方法二的优势是标签会跟随曲线末端移动,每个帧都能看到所有Metal的标签,不会有重叠残留。
内容的提问来源于stack exchange,提问作者OCR
相关产品推荐
相关产品推荐

