如何用R语言基于历年夺冠队伍数据制作动态竞赛条形图
数据集构造修正
你当前使用spread()转换为宽表的操作不符合动态竞赛条形图的输入要求,这类图表需要长面板数据结构,即每一行对应「单支队伍+单个年份+截止当年累计夺冠次数」的组合,且需要补全所有队伍在所有年份的记录,避免动画断层。
数据集构造代码如下:
library(tidyverse) # 提取所有参赛队伍 all_teams <- unique(df$Team) # 生成所有年份和所有队伍的完整交叉组合 full_panel <- expand.grid( Year = seq(min(df$Year), max(df$Year), 1), Team = all_teams ) %>% # 关联原始夺冠记录,夺冠年份标记为1,非夺冠年份标记为0 left_join(df %>% mutate(win = 1), by = c("Year", "Team")) %>% replace_na(list(win = 0)) %>% # 按队伍分组计算累计夺冠次数 group_by(Team) %>% arrange(Year) %>% mutate(cum_champion = cumsum(win)) %>% ungroup()
运行后得到的full_panel就是符合绘图要求的数据集。
动态竞赛条形图绘制
使用gganimate包实现动画效果,导出GIF需要配合gifski包,先安装依赖:
install.packages(c("gganimate", "gifski"))
绘图及导出代码如下:
library(gganimate) # 绘制基础图表 bar_race_plot <- full_panel %>% # 每年取累计夺冠次数前10的队伍,避免条形过多显示混乱,可自行调整数值 group_by(Year) %>% mutate(rank = rank(-cum_champion, ties.method = "first")) %>% filter(rank <= 10) %>% ungroup() %>% ggplot(aes(x = rank, y = cum_champion, fill = Team, group = Team)) + geom_col(width = 0.7, alpha = 0.8) + # 条形左侧显示队伍名称 geom_text(aes(y = 0, label = Team), hjust = 1.1, size = 5) + # 条形右侧显示累计夺冠次数 geom_text(aes(y = cum_champion, label = as.character(cum_champion)), hjust = -0.1, size = 4.5) + # 翻转坐标轴为横向条形 coord_flip(clip = "off") + # 反转x轴让排名第一的队伍在最上方 scale_x_reverse() + theme_minimal() + theme( axis.text.y = element_blank(), axis.title.y = element_blank(), axis.ticks.y = element_blank(), legend.position = "none", plot.margin = margin(1, 4, 1, 6, "cm") ) + # 动态过渡配置 transition_states(Year, transition_length = 3, state_length = 1) + ease_aes('cubic-in-out') + labs(title = "锦标赛累计夺冠数 年份:{closest_state}", y = "累计夺冠次数") # 导出为GIF动图 animate(bar_race_plot, nframes = 400, fps = 10, renderer = gifski_renderer("champion_race.gif"), width = 800, height = 600)
可根据需求调整帧数、帧率、画布尺寸等参数,导出的GIF会保存在当前工作目录下。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

