You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在gganimate动态本垒打图中切换对手MLB队徽?

动态MLB本垒打动画:实现对手队徽随帧切换

当然可以实现队徽随动画帧切换,核心问题是**annotate()是静态标注,不会随动画帧更新**,需要改用geom_mlb_scoreboardlogo()结合数据映射来实现动态变化。

修改步骤

  1. 移除原代码中固定队徽的两行annotate(GeomMLBscoreboardlogo)
  2. 添加geom_mlb_scoreboardlogo(),直接映射MorelHR中的Opponent列到team_abbr参数,同时设置固定的坐标位置

修改后的完整代码

library(tidyverse)
library(mlbplotr)
library(geommlbstadiums)
library(ggtext)
library(gganimate)

MorelHR <- data.frame(
  ID = c(663611, 663611), 
  launch_speed = c(98.2, 94.5), 
  launch_angle = c(26, 37), 
  hit_distance_sc = c(390, 362), 
  HR = c(1, 2), 
  Opponent = c("CLE", "CWS"), 
  x_coord = c(-115.2, -189.7), 
  y_coord = c(374.3, 310.4))

Positions <- data.frame(
  HR = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2), 
  player_name2 = c("Bo Naylor", "Josh Bell", "Andrés Gimenez", "Amed Rosario", "Tyler Freeman", 
                   "David Fry", "Myles Straw", "Will Brennan", "Yasmani Grandal", "Gavin Sheets", "Elvis Andrus", 
                   "Tim Anderson", "Yoán Moncada", "Andrew Benintendi", "Luis Robert", "Oscar Colás"), 
  fielder_x = c(0, 57.5, 50, -50, -57.5, -130, 0, 130, 0, 57.5, 50, -50, -57.5, -130, 0, 130), 
  fielder_y = c(-20, 60, 120, 120, 60, 220, 310, 220, -20, 60, 120, 120, 60, 220, 310, 220))

MorelHR %>%
  ggplot(aes(x = x_coord, y = y_coord)) +
  geom_segment(aes(x = 0, y = 0, xend = x_coord, yend = y_coord)) +
  geom_spraychart(stadium_ids = "cubs", stadium_transform_coords = T, stadium_segments = "all") +
  geom_point(color = "red", size = 3) +
  geom_label(data = Positions, aes(x = fielder_x, y = fielder_y, label = player_name2,
                                  color = color2, fill = color1, fontface = "bold")) +
  scale_x_continuous(limits = c(-325, 325)) +
  annotate(GeomMLBheads, player_id = 663611, width = 0.5, x = -225, y = 10) +
  # 替换为动态队徽映射
  geom_mlb_scoreboardlogo(aes(team_abbr = Opponent), width = 0.1, x = 0, y = 210) +
  geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf), color = "black", fill = NA) +
  labs(title = "Home Run Count: {current_frame}",
       subtitle = paste("v.", "**{filter(MorelHR, HR == current_frame) %>% pull(Opponent) %>% .[[1]]}**", "|",
                        "**{filter(MorelHR, HR == current_frame) %>% pull(launch_speed) %>% .[[1]]}**", "mph |",
                        "**{filter(MorelHR, HR == current_frame) %>% pull(launch_angle) %>% .[[1]]}**", "degrees |",
                        "**{filter(MorelHR, HR == current_frame) %>% pull(hit_distance_sc) %>% .[[1]]}**", "ft"),
       caption = "Data courtesy of MLB Advanced Media | **@GoCubs49**", x = NULL, y = NULL) +
  theme_void() +
  theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 20), plot.subtitle = element_markdown(hjust = 0.5, size = 18),
        plot.caption = element_markdown(size = 11, hjust = 0.98)) +
  scale_color_identity() +
  scale_fill_identity() +
  guides(color = "none", fill = "none") +
  transition_manual(HR) +
  enter_fade() +
  ease_aes("linear")

额外说明

原代码的subtitle中调用了pull(player_name2),但MorelHR数据框里并没有这个列,我已经把它改成了pull(Opponent),这样副标题里的对手名称也会随帧更新,和队徽对应。

内容的提问来源于stack exchange,提问作者stevoo_p13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:14:54