knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(tidyverse)
library(lubridate)
library(cowplot)
library(gganimate)
library(scryr)
library(mtggplot)

How has the number of commanders available to each color grown over time? Technically, we could just use scry_cards("is:commander"), but we using a more complicated search because we want to include at least one card from each set that added cards to the format. That will make it easier to count new commanders by set, even when that number is zero. We're also exluding a few promotional sets (book promos, Game Night, the M19 Gift Pack, and Nalathni Dragon). We're also excluding Archenemy and Planechase because they each has one non-legendary creature (and three other cards) that would see print shortly thereafter in M11 and Zendikar, respectively.

legal_cmder_search <- scry_cards("(t:creature or is:commander') not:reprint f:commander -set:pdrc -set:gnt -set:phpr -set:g18 -set:arc -set:hop") %>% 
  # keep object smaller by just using columns we need
  select(name, released_at, type_line, colors, color_identity, set_name)

# writing to local file to avoid having to re-run query
# write_rds(legal_cmder_search, here::here("vignettes", "legal_cmder_search.rds"))
# legal_cmder_search <- read_rds(here::here("vignettes", "legal_cmder_search.rds"))

To wrangle the data into the shape we want it, we to a) make sure sets are sorted by release date (released_at), b) count number of new legal commanders by set and color identical (lumping all 2+ color commanders together), c) do so in a way that includes a 0 for set/color combinations with no new commanders, and d) total number of commanders by color id to date for each set.

legal_cmder_search <- legal_cmder_search %>% 
  # released_at is read in from the API as string rather than a date
  mutate(released_at = ymd(released_at),
         set_name = fct_reorder(set_name, released_at),
         is_cmder = str_detect(type_line, "Legendary"),
         color_identity = map_chr(color_identity, relabel_mtg_color))


cmd_count <- legal_cmder_search %>% 
  count(set_name, color_identity, is_cmder, released_at) %>% 
  pivot_wider(names_from = is_cmder, 
              values_from = n, 
              values_fill = list(n = 0)) %>% 
  select(set_name, color_identity, new_cmd = `TRUE`,released_at) %>% 
  complete(set_name, color_identity, fill = list(new_cmd = 0)) %>% 
  # to get fill() to work correctly
  arrange(set_name, released_at) %>% 
  group_by(color_identity) %>% 
  mutate(cmd_to_date = cumsum(new_cmd)) %>% 
  ungroup() %>% 
  group_by(set_name) %>% 
  mutate(set_new_cmd = sum(new_cmd)) %>%
  tidyr::fill(released_at) %>% 
  ungroup()

# we want to add some trivia to set_name
# code to find oldest color/color id mismatch (Homelands: Daughter of Autumn)
# legal_cmder_search %>%
#   filter(str_detect(type_line, "Legendary"),
#          !map2_lgl(colors, color_identity,identical))
# first mono-colored commanders 
# filter(cmd_count, new_cmd > 0, color_identity != "Multicolored")
# first colorless commanders
# filter(cmd_count, new_cmd > 0, color_identity == "Colorless")

cmd_count <- cmd_count %>% 
  mutate(set_name = str_replace(set_name, "Legends", "LEGENDS!!!"),
         set_name = str_replace(set_name, "Ice Age", 
                                "Ice Age (1st mono-colored commanders: General Jarkeld(W)\n& Márton Stromgald(R))"),
         set_name = str_replace(set_name, "Homelands", 
                                "Homelands (1st commander where \ncolor =/= color ID: Daughter of Autumn"),
        set_name = str_replace(set_name, "Visions",
                               "Visions (Last Standard-legal expansion with \nno new Legends)"),
        set_name = str_replace(set_name, "Stronghold",
                               "Stronghold (1st 5-color commander: Sliver Queen)"),
        set_name = str_replace(set_name, "Urza's Saga",
                               "Urza's Saga (1st colorless commander: Karn, Silver Golem)"),
        set_name = str_replace(set_name, "Urza's Destiny",
                               "Urza's Destiny (Oldest banned commander: Rofellos, \nLlanowar Emissary)"),
        set_name = str_replace(set_name, "Odyssey", 
                               "Odyssey (With apologies to @CubeApril)"),
        set_name = str_replace(set_name, "Commander 2011", 
                               "Commander 2011 (1st Commander-specific product)"),
        set_name = str_replace(set_name, "Magic 2013", 
                               "Magic 2013 (1st core set with new Legends)"),
        set_name = str_replace(set_name, "Commander 2014", 
                               "Commander 2014 (Planswalker commanders)"),
        set_name = str_replace(set_name, "Commander 2016", 
                               "Commander 2016 (4-color commanders! Partner!)"),
        set_name = str_replace(set_name, "Battlebond", 
                               "Battlebond (Partner with)"))

Now we just need to plot and animate our data.

# we can't directly reference the columns we need for labels, so we need to 
# build helper functions
get_set_name <- function(frame_date){
  cmd_count %>% 
    filter(released_at <= frame_date) %>% 
    slice(n()) %>% 
    pull(set_name) 
}

get_new_cmds <- function(frame_date){
  cmd_count %>% 
    filter(released_at <= frame_date) %>% 
    slice(n()) %>% 
    pull(set_new_cmd) 
}

cmd_anim <- ggplot(cmd_count, aes(x = released_at, 
                                 y = cmd_to_date, 
                                 color = color_identity,
                                 group = color_identity)) +
  geom_line(size = 1, key_glyph = "timeseries") + 
  geom_point(size = 2, key_glyph = "timeseries") +
  scale_color_manual(values = mtg_cols()) +
  theme_cowplot() +
  # color code taking from card back
  theme(panel.background = element_rect(fill = "lightsteelblue"),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        legend.position = "bottom")  +
  transition_reveal(released_at) + 
  view_follow(fixed_x = TRUE) +
  labs(subtitle = "Latest release: {get_set_name((frame_along))} 
       New commanders: {get_new_cmds((frame_along))}",
       y = "Total legal commanders",
       color = "Color ID",
       caption = "Created by Karl Hailperin (@khailper)")

set_count <- cmd_count %>% 
  pull(set_name) %>% 
  unique() %>% 
  length()

animate(cmd_anim, nframes = set_count * 5)

We should also make it available as a video:

animate(cmd_anim, 
        nframes = set_count * 5, 
        renderer = av_renderer())


khailper/mtggplot documentation built on July 17, 2019, 7:19 p.m.