Last week, the NFL Players Association (NFLPA) dropped a bombshell set of data: reviews by thirteen hundred active NFL players, of their own teams. Players graded their teams from A+ to F- on the following dimensions of player experience:
- Treatment of Families
- Nutrition
- Weight Room
- Strength Staff
- Training Room
- Training Staff
- Locker Room
- Travel
The NFLPA’s website is interactive and offers some entertaining anecdotes - such as the fact that the Arizona Cardinals charge their players for meals at the team facility!
Unfortunately, as good as the NFLPA’s data is, the presentation is a bit lacking… which left me a nice opening to build some quick visuals to better convey the information!
So, take a peek below: I’ve created a heatmap version of the league-wide ratings display on the NFLPA site, and also built out some fun division-by-division circumplex charts that provide a bit more visual pop!
League-wide Report Cards
Divisional Circumplex Charts
In addition to our league-wide heatmap, I thought it might be fun to visualize these results as polar bar charts, on a per-division basis. If these look familiar, it’s because I copied a how-to that I wrote a few years ago to help with the base chart formatting - pretty fun!
AFC East
AFC North
AFC South
AFC West
NFC East
NFC North
NFC South
NFC West
Visualization Code
Heatmap
library(colorspace)
m_df %>% ggplot(aes(x = variable, y = Team, label = value, fill = value)) +
geom_tile() +
scale_y_discrete(limits=rev) +
scale_fill_discrete_diverging(
palette = "Red-Green",
limits = c("F-", "F", "F+", "D-", "D", "D+", "C-", "C", "C+", "B-", "B", "B+", "A-", "A", "A+"),
rev = FALSE,
alpha = 0.8
) +
geom_text() +
scale_x_discrete(position = "top") +
theme_minimal() +
theme(
plot.title = element_text(size = 20, face = "bold"),
plot.subtitle = element_text(size = 12),
plot.caption = element_text(size = 8, colour = "grey60"),
axis.text.x = element_text(angle = 30, hjust = 0),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none",
plot.title.position = "plot"
) +
labs(
title = "NFL Player Team Report Cards",
subtitle = "1,300 members of the NFL Players Association (NFLPA) completed report cards following\nthe 2022-2023 season, evaluating their team on key variety of key player experience areas.\nThe responses show some standout clubs, such as the Minnesota Vikings and Miami\nDolphins, but also laggards such as the Arizona Cardinals and Washington Commanders.",
x = '',
y = '',
caption = "Data from NFLPA.com\nconormclaughlin.net"
)
Circumplex Charts
create_faceted_polar_charts <- function(input_division) {
p <- ggplot(m_df %>% filter(division == input_division), aes(x = str_replace(variable, " ", "\n"), y = reorder(value, desc(value)), group = Team, fill = variable, label = value)) +
geom_col(width = 0.87) +
geom_text_repel(size = 3, nudge_y = -0.5, fontface = "bold") +
scale_y_discrete(limits = c("F-", "F", "F+", "D-", "D", "D+", "C-", "C", "C+", "B-", "B", "B+", "A-", "A", "A+")) +
facet_wrap(~ Team, nrow = 2, ncol = 2) +
coord_polar(clip = "on") +
theme_minimal() +
theme(
legend.position = "none",
strip.background = element_rect(fill = "grey30"),
strip.text = element_text(color = "grey97", face = "bold"),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.ticks = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size = 8, face = "bold"),
plot.title = element_text(size = 20, face = "bold"),
plot.subtitle = element_text(size = 12),
plot.caption = element_text(colour = "grey60")
) +
labs(
x = "",
y = "",
title = "NFL Player Team Report Cards",
subtitle = paste0("Division: ", input_division),
caption = "Data from NFLPA.com\nconormclaughlin.net"
)
p
ggsave(paste0("nflpa_survey_report_card_", sub(" ", "_", tolower(input_division)), "_2022_2023.png"), height = 8, width = 7, units = "in", dpi = 500, bg = "white")
return(p)
for(i in unique(m_df$division))
create_faceted_polar_charts(i)