Visualizing an NBA Team’s Schedule Using R

[This article was first published on r on Tony ElHabr, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

If you’re not completely new to the data science community (specifically, the #rstats community), then you’ve probably seen a version of the “famous” data science workflow diagram. 1

If one is fairly familiar with a certain topic, then one might not spend much time with the initial “visualize” step of the workflow. Such is the case with me and NBA data–as a relatively knowledgeable NBA follower, I don’t necessarily need to spend much of my time exploring raw NBA data prior to modeling.

Anyways, as a break from experimenting with predictive models, I decided to make a visualization just for the sake of trying something I hadn’t done before. 2 In particular, I was inspired by the calendar heat map visualization that I saw in the Top 50 ggplot visualizations post on the website.

To implement a plot of this nature, I decided to look at how my hometown team, the San Antonio Spurs, fared last season (2016) in terms of point differential. In case it’s not immediately obvious, lots of green is good. (This is not surprising to those of us who follow the NBA–the Spurs have been consistently good since the end of the 1990s.)


url <- ""
results_prepared <- getURL(url)

colnames_base <- c("date", "season", "tm")
colnames_calc_dates <- c("yyyy", "mm", "dd", "wd", "mm_yyyy", "mm_w")
# Look at a couple of different metrics.
# Specifically, look at games played to date (g_td) and point differential (pd).
colnames_viz <- c("g_td", "pd")

results_calendar_tm <-
  results_prepared %>%
  filter(tm == "SAS") %>%
    yyyy = year(date),
    mm = lubridate::month(date),
    dd = lubridate::day(date),
    wd = lubridate::wday(date, label = TRUE, abbr = TRUE),
    mm_yyyy = zoo::as.yearmon(date)
  ) %>%
  group_by(mm_yyyy) %>%
  mutate(mm_w = ceiling(dd / 7)) %>%
  ungroup() %>%
  select(one_of(colnames_base, colnames_calc_dates, colnames_viz)) %>%
  arrange(season, g_td, tm)

# Tidy up because I was experimenting with different metrics, not just point differential.
results_calendar_tm_tidy <-
  results_calendar_tm %>%
  # mutate_if(is.character, funs(as.factor)) %>%
  tidyr::gather(metric, value, colnames_viz)

season <- 2016
wd_labels <- levels(results_calendar_tm$wd)
wd_labels[2:6] <- ""
title <- str_c("San Antonio Spurs Point Differential in ", season, " NBA Season")

viz_pd_sas_2016 <-
  results_calendar_tm_tidy %>%
  filter(season %in% seasons) %>%
  filter(metric == "pd") %>%
  ggplot() +
  geom_tile(aes(x = wd, y = mm_w, fill = value), colour = "white") +
  scale_y_reverse() +
  scale_x_discrete(labels = wd_labels) +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
  scale_fill_gradient2(low = "red", mid = "grey", high = "green") +
  theme(legend.position = "bottom") +
  labs(x = "", y = "", title = title) +
  facet_wrap( ~ mm_yyyy, nrow = 2)

There are an infinite number of ways to visualize data like this, but I thought this was interesting because of the temporal nature of the data.

  1. The figure shown here comes from the introductory chapter of the R for Data Science book ^
  2. Here, I use the NBA data that I have already scraped and cleaned. ^

To leave a comment for the author, please follow the link and comment on their blog: r on Tony ElHabr. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)