In the 2023 NFL season, the San Francisco 49ers boasted the league's best run offense. Several factors contributed to their dominance on the ground. The 49ers have long been known for their effective running schemes under head coach Kyle Shanahan, but in 2023, they took it to another level. Key reasons for their success include a healthy offensive line, star running back Christian McCaffrey, and the creative play-calling that kept defenses off balance. The team often utilized motion and pre-snap shifts to create mismatches, while leveraging outside zone schemes and gap-based runs to exploit defenses.
# Calculate the percentage of run plays for each play
games_SF_2023_perc <- games_SF_2023 %>%
filter(posteam == "SF") %>%
select(game_id, posteam, play_type, game_seconds_remaining) %>%
filter(play_type == "run" | play_type == "pass") %>%
group_by(game_id, play_type) %>%
mutate(count_plays = row_number()) %>%
group_by(game_id) %>%
mutate(count_all = row_number()) %>%
ungroup() %>%
mutate(count_run = ifelse(play_type == "run", count_plays, NA)) %>%
fill(count_run) %>%
mutate(perc = (count_run / count_all) * 100)
This visualization helps in understanding the 49ers’ play-calling tendencies. For example, it may reveal whether the team tends to run more when leading or passes more when trailing. With a strong run game, it’s expected that the 49ers leaned heavily on their running attack, especially in the second halves of games where they likely had the lead.
In contrast, the Minnesota Vikings struggled with their run game in 2023, finishing the season with the worst run offense in the league. A combination of a poor offensive line play, injuries at the running back position, and an overall lack of consistency in the ground game led to their struggles. The Vikings often found themselves abandoning the run early in games due to falling behind, further diminishing their effectiveness. Additionally, the lack of a consistent run game made their offense one-dimensional, making it easier for defenses to anticipate passing plays.
# Calculate the percentage of run plays for each play
games_MIN_2023_perc <- games_MIN_2023 %>%
filter(posteam == "MIN") %>%
select(game_id, week_label, posteam, play_type, game_seconds_remaining) %>%
filter(play_type == "run" | play_type == "pass") %>%
group_by(game_id, play_type) %>%
mutate(count_plays = row_number()) %>%
group_by(game_id) %>%
mutate(count_all = row_number()) %>%
ungroup() %>%
mutate(count_run = ifelse(play_type == "run", count_plays, NA)) %>%
fill(count_run) %>%
mutate(perc = (count_run / count_all) * 100)
The visualization produced for the Vikings reveals that they rarely leaned on their run game throughout their 2023 season. This step plot illustrates that the percentage of run plays remained low even in situations where they may have benefited from a balanced approach.
By comparing the two visualizations, we can clearly see the contrast between the best and worst run offenses in the league. While the 49ers consistently utilized their effective run game to control games, the Vikings' lack of a reliable ground attack ultimately led to predictable play-calling and poor overall performance.