This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

In this document, we will replicate the creation of the following plot, called a “Market Map.”

include_graphics("marketmap-original.png")

  1. Read in the in the data
marketmap <- read_csv("marketmap-data.csv")
## Parsed with column specification:
## cols(
##   `Business Line` = col_character(),
##   Jostens = col_double(),
##   `Herff Jones` = col_double(),
##   `AA (Taylor)` = col_double(),
##   Walsworth = col_double(),
##   Lifetouch = col_double(),
##   Walters = col_double(),
##   `Oak Hall (C&G)` = col_double(),
##   `National Rec.(C&G)` = col_double(),
##   `Gaspard (C&G)` = col_double(),
##   `William C&G` = col_double(),
##   `C&G 3` = col_double(),
##   `C&G 4` = col_double(),
##   YB1 = col_double(),
##   YB2 = col_double(),
##   Other = col_double(),
##   Total = col_integer()
## )
  1. Create a tibble with the company names that are contained in the header row of the raw data. We also remove the first and last column to just get the company names.
companies <-
  tibble(company = names(marketmap)[2:(ncol(marketmap) - 1)])
  1. Create a named vector for the colors and companies for a custom color scheme. In this vector me map the value of the company name to a color in hexadecimal format. This will be used later with the scale_fill_manual color scale.
color_vector <- map_chr(companies$company,
                        function(x)
                          switch(
                            x,
                            "Jostens" = "#416433",
                            "Herff Jones" = "#FCE44C",
                            "AA (Taylor)" = "#BF6D68",
                            "Other" = "#FFFFFF",
                            "#A2CBFA"
                          ))
names(color_vector) <- companies %>% pull(company)
color_vector
##            Jostens        Herff Jones        AA (Taylor) 
##          "#416433"          "#FCE44C"          "#BF6D68" 
##          Walsworth          Lifetouch            Walters 
##          "#A2CBFA"          "#A2CBFA"          "#A2CBFA" 
##     Oak Hall (C&G) National Rec.(C&G)      Gaspard (C&G) 
##          "#A2CBFA"          "#A2CBFA"          "#A2CBFA" 
##        William C&G              C&G 3              C&G 4 
##          "#A2CBFA"          "#A2CBFA"          "#A2CBFA" 
##                YB1                YB2              Other 
##          "#A2CBFA"          "#A2CBFA"          "#FFFFFF"
  1. Create an order column in the company tibble to control the order that the companies will be displayed in the y order.
companies <- companies %>%
  mutate(co_order = map_int(company,
                            function(x)
                              switch(
                                x,
                                "Jostens" = 1L,
                                "Herff Jones" = 2L,
                                "AA (Taylor)" = 3L,
                                "Other" = 5L,
                                4L
                              )))
  1. Create tidy dataset: remove the Total column from read data and transform it to long
mm_long <- marketmap %>%
  select(-Total) %>%
  rename(product = `Business Line`) %>%
  gather(-product,
         key = "company",
         value = "revenue",
         na.rm = T)
mm_long
## # A tibble: 27 x 3
##    product           company     revenue
##  * <chr>             <chr>         <dbl>
##  1 Yearbook          Jostens       388. 
##  2 Cap & Gown        Jostens        73.8
##  3 Rings             Jostens       216  
##  4 Diplomas & Awards Jostens        33.4
##  5 Yearbook          Herff Jones   204. 
##  6 Cap & Gown        Herff Jones    73.8
##  7 Rings             Herff Jones   162  
##  8 Diplomas & Awards Herff Jones    27.4
##  9 Yearbook          AA (Taylor)   102. 
## 10 Cap & Gown        AA (Taylor)     5.9
## # ... with 17 more rows
  1. Total the revenue by product, and for each product define the order in the x axis, as well as the coordinates of the starting and ending point
tot_by_prod <- mm_long %>%
  group_by(product) %>%
  summarise(tot_rev_by_prod = sum(revenue)) %>%
  ungroup() %>%
  mutate(prod_order = map_int(product, function(x)
    switch(
      x,
      "Yearbook" = 1L,
      "Cap & Gown" = 2L,
      "Rings" = 3L,
      4L
    ))) %>%
  arrange(prod_order) %>%
  mutate(
    x_start = cumsum(tot_rev_by_prod) - tot_rev_by_prod,
    x_end = x_start + tot_rev_by_prod
  )
  1. Join the product and company attributes back to the long data. Now you have one row per data point with most of the attributes you need to plot.
mm_long <- mm_long %>%
  inner_join(companies) %>%
  inner_join(tot_by_prod)
## Joining, by = "company"
## Joining, by = "product"
  1. Create a new dataset called ads (analytical dataset) and define additional attributes
ads <- mm_long %>%
  ungroup() %>%
  mutate(pct_of_prod = revenue / tot_rev_by_prod) %>%
  group_by(product) %>%
  arrange(co_order, desc(revenue)) %>%
  mutate(y_start = cumsum(pct_of_prod) - pct_of_prod,
         y_end = y_start + pct_of_prod)
  1. Now we have all the attributes we need. Generate the base plot:
base_plot <- ggplot(ads) +
  geom_rect(aes(
    xmin = x_start,
    xmax = x_end,
    ymin = y_start,
    ymax = y_end,
    fill = company
  ),
  color = "black") +
  scale_fill_manual(values = color_vector)
base_plot

  1. We need to add some text values and change theme components to get to the final plot
final_plot <- 
base_plot +
  geom_text(
    aes(x = (x_start + x_end) / 2,
        y = (y_start + y_end) / 2,
        label = company),
    color = ifelse(ads$company == "AA (Taylor)", "white", "black")
  ) +
  geom_text(data = tot_by_prod,
            aes(
              x = (x_start + x_end) / 2 ,
              y = -0.01,
              vjust = 1,
              label = product
            )) +
  geom_text(aes(
    x = (x_start + x_end) / 2 ,
    y = 1.00,
    vjust = -1,
    #size = tot
    label = scales::comma(tot_rev_by_prod)
  )) +
  theme_bw() +
  scale_y_continuous(breaks = seq(0, 1, 0.2), labels = scales::percent) +
  ggtitle("Market Map - Current Segments - Scholastic and Memory Books") +
  theme(
    plot.title = element_text(face = "bold",
                              size = 20,
                              hjust = 0.5),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_blank(),
    axis.line.x = element_blank(),
    axis.text.x = element_blank(),
    axis.text.y = element_text(face = "bold", size = 12),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    axis.ticks.x = element_blank(),
    panel.border = element_blank(),
    legend.position = "none"
  )
final_plot