Recreation of Cole Nussbaumer Knaflic’s Storytelling with Data (Wiley, 2015) plots using R an ggplot2.

Original data provided by the book’s author https://www.storytellingwithdata.com/book/downloads

library(ggtext)
## Warning: package 'ggtext' was built under R version 4.0.5
library(tidyselect)
library(ggplot2)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v tibble  3.0.5     v dplyr   1.0.3
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.0
## v purrr   0.3.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
library(gridtext)
## Warning: package 'gridtext' was built under R version 4.0.5

Chapter 2: Choosing an effective visual

Simple text

df_box <- tibble(
  label = c("<span style='font-size:128pt;color:#31859C'>**20%**</span> <br/> 
  <span style='font-size:20pt;color:#7F7F7F'>**of children had a**</span><br/>
  <span style='font-size:20pt;color:#31859C'>**traditional stay-at-home mom** </span><br/>
  <span style='font-size:20pt;color:#7F7F7F'>**in 2012, compared to 41% in 1970**</span>"),
  x = 0.01, 
  y = 0.5,
  color = c("white"),
  fill = c("white"))

ggplot()+
  geom_textbox(data = df_box, 
               aes(x , y, label = label), 
               box.color = "white", 
               fill = "white", lineheight = 2,
               width = unit(400, "pt"),
               hjust = 0,
               box.padding = unit(c(0, 0, 0, 0), "pt")) + # control the width
  xlim(0, 1) + 
  ylim(0, 1) +
  theme(axis.ticks.x = element_blank(),
       axis.ticks.y = element_blank(),
       axis.title = element_blank(),
       axis.line = element_blank(),
       axis.text.y = element_blank(),
       axis.text.x = element_blank(),
       axis.title.x = element_blank(),
       axis.title.y = element_blank(),
       panel.grid.major = element_blank(),
       panel.grid.minor = element_blank(),
       panel.background = element_blank(),
       plot.margin = unit(c(0,0,0,0),"cm"))

Figure 2.3 Stay-at-home moms simple text makeover

ggsave("Figure 2.3 Stay-at-home moms simple text makeover.png", height = 7, width = 11,units = "in",dpi = 300)

Scatter Plot

miles <- read_csv("milesdriven.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   `Miles Driven` = col_number(),
##   `Cost Per Mile` = col_double()
## )
avg_cost <- mean(miles$`Cost Per Mile`)
avg_mile <- mean(miles$`Miles Driven`)


ggplot(data = miles,aes(x = `Miles Driven`, y = `Cost Per Mile`)) +
  
  geom_point(data = filter(miles,`Cost Per Mile` < avg_cost),color = "#BFBEBE",size = 5)+
  geom_point(data = filter(miles,`Cost Per Mile` >= avg_cost),color = "#F79747",size = 5) +
  
  geom_hline(yintercept = avg_cost, linetype = "longdash") + 
  geom_point(x = avg_mile,y = avg_cost, size = 6) +
  geom_label(x = avg_mile, y = avg_cost, label = "AVG", hjust = 1.25, label.size = 0) + 
  
  scale_x_continuous(expand = c(0, 0),limits = c(0, 4000), n.breaks = 5) +
  scale_y_continuous(expand = c(0, 0),limits = c(0, 3),labels = scales::dollar_format(), n.breaks = 7) +
  
  labs(title = "Cost per mile by miles driven",
       x =  "Miles driven per month",
       y = "Cost per mile") +
  
  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        
        # axis.title.y = element_text(hjust = 1, margin = margin(0, 6, 0, 15, "pt")),
        # axis.title.x = element_text(hjust = 0, margin = margin(6, 0, 15, 0, "pt")),
        axis.title.x= element_text(size = 12, hjust = 0, vjust = -1, color = "#555655"),
        axis.title.y = element_text(size = 12, hjust = 1 ,vjust = 1, color = "#555655"),
        
        axis.text.x = element_text(color ="#777B7E", face="bold"),
        axis.text.y = element_text(color ="#777B7E", face="bold"),        
        
        axis.ticks.x = element_line(color="#a9a9a9"),
        axis.ticks.y = element_line(color="#a9a9a9"),
      
        axis.line.x = element_line(color="grey", size = 1),
        axis.line.y = element_line(color="grey", size = 1),
        
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        
         plot.margin = margin(.5,.5,.5,.5,"cm"))

Figure 2.7 Modified Scatterplot

ggsave("Figure 2.7 Modified Scatterplot.png", height = 7, width = 11,units = "in",dpi = 300)

Line graph

passport <- read_csv("passport.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   year = col_double(),
##   month = col_character(),
##   Min = col_double(),
##   Avg = col_double(),
##   Max = col_double(),
##   `Max to graph` = col_double()
## )
theme_ch2 <-  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        plot.subtitle = element_markdown(size =14),
        # axis.title.y = element_text(hjust = 1, margin = margin(0, 6, 0, 15, "pt")),
        # axis.title.x = element_text(hjust = 0, margin = margin(6, 0, 15, 0, "pt")),
        axis.title.x =  element_text(size = 12, hjust = 0, vjust = -1, color = "#555655"),
        axis.title.y = element_text(size = 12, hjust = 1 ,vjust = 1, color = "#555655"),
        
        axis.text.x = element_text(size = 12,color ="#777B7E", face="bold"),
        axis.text.y = element_text(size = 12,color ="#777B7E", face="bold"),        
        
        axis.ticks.x = element_line(color="#a9a9a9"),
        axis.ticks.y = element_line(color="#a9a9a9"),
      
        axis.line.x = element_line(color="grey", size = 1),
        axis.line.y = element_line(color="grey", size = 1),
        
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        
         plot.margin = margin(.5,.5,.5,.5,"cm"))
passport <- passport %>% 
  mutate(date = ymd(paste(year, month, 1)))
passport %>% 
  filter(date== "2014-09-01")
## # A tibble: 1 x 7
##    year month   Min   Avg   Max `Max to graph` date      
##   <dbl> <chr> <dbl> <dbl> <dbl>          <dbl> <date>    
## 1  2014 Sep       9    18    27             18 2014-09-01
ggplot(data = passport) +
  geom_ribbon(aes(x= date, ymin = Min, ymax = Max), fill = "grey70") +
  geom_line(aes(x= date, y = Avg), size = 2) + 
  geom_point(data= filter(passport, date == "2015-09-01"), aes(x= date, y = Avg), size = 5) +
  
  annotate("text", x = as.Date("2015-09-20"), y = 21, label = "21", color = "black", size = 5) +
  annotate("text", x = as.Date("2014-09-15"), y = 10, label = "MIN", color = "#76787B", size = 5) +
  annotate("text", x = as.Date("2014-09-15"), y = 20, label = "AGV", color = "black", size = 5,fontface =2) +
  annotate("text", x = as.Date("2014-09-15"), y = 25, label = "MAX", color = "#76787B",size = 5) +
  
  scale_x_date(expand = c(0, 0),
               labels = function(x) if_else(is.na(lag(x)) | !year(lag(x)) == year(x), 
                                             paste(month(x, label = TRUE), "\n", year(x)), 
                                             paste(month(x, label = TRUE))),
               limits = c(ymd("2014-08-16"), ymd("2015-10-01")),
               breaks = passport$date) + # n.breaks does not work
  scale_y_continuous(expand = c(0, 0), 
                     limit = c(0, 40), 
                     n.breaks = 9) +
  
  labs(title = "Passport control wait time",
       subtitle = "Past 13 months",
       y = "Wait time (minutes)") +

  coord_cartesian(clip = "off") +
  theme_ch2 +
  theme(axis.title.x =  element_blank(),
        plot.margin = margin(.5,0.5,0.5,0.5,"cm"))

Figure 2.9 Showing average within a range in a line graph

ggsave("Figure 2.9 Showing average within a range in a line graph.png", height = 7, width = 11,units = "in",dpi = 300)

Slopegraphe

feedback <- read_csv("feedback.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   Category = col_character(),
##   `2014` = col_double(),
##   `2015` = col_double()
## )
feedback
## # A tibble: 7 x 3
##   Category              `2014` `2015`
##   <chr>                  <dbl>  <dbl>
## 1 Culture                   80     96
## 2 Peers                     85     91
## 3 Work environment          76     75
## 4 Leadership                59     62
## 5 Rewards & recognition     41     45
## 6 Perf management           33     42
## 7 Career development        49     33
df_long <- feedback %>% 
  pivot_longer(cols = c("2014","2015"), 
               names_to = "year", 
               values_to = "percent")

head(df_long,10)
## # A tibble: 10 x 3
##    Category              year  percent
##    <chr>                 <chr>   <dbl>
##  1 Culture               2014       80
##  2 Culture               2015       96
##  3 Peers                 2014       85
##  4 Peers                 2015       91
##  5 Work environment      2014       76
##  6 Work environment      2015       75
##  7 Leadership            2014       59
##  8 Leadership            2015       62
##  9 Rewards & recognition 2014       41
## 10 Rewards & recognition 2015       45
ggplot(data = df_long)+ 
  #Line
  geom_line(aes(x = year, y  = percent, group= Category), 
            size = 1.5, color ="#76787B") +
  geom_line(data = filter(df_long, Category == "Career development"), 
            aes(year, percent,group= Category), 
            size = 1.5, color = "#FF3403") +
  #point
  geom_point(aes(x = year, y  = percent, group= Category), 
             size = 3, color ="#76787B") +
  geom_point(data = filter(df_long, Category == "Career development"), 
             aes(year, percent), 
             size = 3, color = "#FF3403") +
  
  #Percent-labels
  geom_text(data= filter(df_long, year== 2014),aes(x= year,y = percent, label=paste(percent,"%",sep = "")),
            nudge_x = -.2, color ="#76787B") +
  geom_text(data= filter(df_long, year== 2015),aes(x= year,y = percent, label=paste(percent,"%",sep = "")),
            nudge_x = .25, color ="#76787B") +
  geom_text(data= filter(df_long, year == 2014, Category == "Career development"),
            aes(x= year,y = percent, label=paste(percent,"%",sep = "")),
            nudge_x = -.2, color ="#FF3403") +
  geom_text(data= filter(df_long, year == 2015, Category == "Career development"),
            aes(x= year,y = percent, label=paste(percent,"%",sep = "")),
            nudge_x = .25, color = "#FF3403") +
  
  # Category-labels
  geom_text(data= filter(df_long, year == 2014),
            aes(x= year,y = percent, label=paste(Category)),
            nudge_x = -.4,hjust = 1, color ="#76787B") +
  geom_text(data= filter(df_long, year == 2014, Category == "Career development"),
            aes(x= year,y = percent, label=paste(Category)),
            nudge_x = -.4,hjust = 1, color = "#FF3403") +
  
  scale_x_discrete(expand = expansion(2,0), 
                   limits = c("2014","2015"), 
                   labels = c(2014,2015)) +
  scale_y_continuous(limits = c(20,100)) +
  
  labs(title = "Employee feedback over time", 
       x = "Survey Year", 
       subtitle = "Survey Category | Percent Favorable") +
  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        plot.subtitle = element_markdown(size =14, hjust =  0.15, color = "#76787B"),
        # axis.title.y = element_text(hjust = 1, margin = margin(0, 6, 0, 15, "pt")),
        # axis.title.x = element_text(hjust = 0, margin = margin(6, 0, 15, 0, "pt")),
        axis.title.x =  element_text(size = 12, hjust = 0, vjust = -1, color = "#555655"),
        axis.title.y = element_blank(),
        
        axis.text.x = element_text(size = 12,color ="#777B7E", face="bold"),
        axis.text.y = element_blank(),        
        
        axis.ticks.x = element_line(color="#a9a9a9"),
        axis.ticks.y = element_blank(),
      
        axis.line.x = element_line(color="grey", size = 1),
        # axis.line.y = element_line(color="grey", size = 1),
        
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        
         plot.margin = margin(.5,.5,.5,.5,"cm"))

Figure 2.11 Modified slopegraph (page 49)

ggsave("Figure 2.11 Modified slopegraph.png", height = 7, width = 11,units = "in",dpi = 300)

bars: Stacked horizontal bar chart (FIG2.19)

survey <- read_csv("survey.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   items = col_character(),
##   `Strongly Disagree` = col_character(),
##   Disagree = col_character(),
##   Neutral = col_character(),
##   Agree = col_character(),
##   `Strongly Agree` = col_character()
## )
survey
## # A tibble: 5 x 6
##   items         `Strongly Disagree` Disagree Neutral Agree `Strongly Agree`
##   <chr>         <chr>               <chr>    <chr>   <chr> <chr>           
## 1 Survey item E 5%                  5%       30%     27%   33%             
## 2 Survey item D 6%                  11%      35%     28%   20%             
## 3 Survey item C 6%                  14%      45%     15%   20%             
## 4 Survey item B 8%                  32%      20%     23%   17%             
## 5 Survey item A 16%                 25%      32%     18%   9%

Transforming data

df_long <- survey %>%
  pivot_longer(cols = c("Strongly Disagree","Disagree","Neutral","Agree","Strongly Agree"),
               names_to = "Scale",
               values_to = "Percent") %>%
  mutate(percent = as.numeric(str_remove(Percent,"%")))
  
df_long$Scale <- factor(df_long$Scale,levels=c("Strongly Agree","Agree", "Neutral","Disagree","Strongly Disagree"))

head(df_long, 10)
## # A tibble: 10 x 4
##    items         Scale             Percent percent
##    <chr>         <fct>             <chr>     <dbl>
##  1 Survey item E Strongly Disagree 5%            5
##  2 Survey item E Disagree          5%            5
##  3 Survey item E Neutral           30%          30
##  4 Survey item E Agree             27%          27
##  5 Survey item E Strongly Agree    33%          33
##  6 Survey item D Strongly Disagree 6%            6
##  7 Survey item D Disagree          11%          11
##  8 Survey item D Neutral           35%          35
##  9 Survey item D Agree             28%          28
## 10 Survey item D Strongly Agree    20%          20
cols <- c("Strongly Disagree" = '#404040',
          "Disagree" = '#404040',
          "Neutral"= '#BFBFBF' ,
          "Agree"= '#1F497D',
          "Strongly Agree"= '#1F497D')

ggplot(data = df_long) + 
  geom_bar(stat = "identity", 
           aes(x = items, y = percent, fill = Scale), 
           width = 0.65, 
           color = "white")+
  
  scale_y_continuous(name = "Percent of total", 
                     limits = c(0, 100),
                     breaks = seq(0, 100, by = 20),
                     labels = function(x) paste0(x,"%"),
                     position = 'right') +
  
  labs(title= "Survey results",
       subtitle = "<span style='color:#404040'>Strongly Disagree</span>| 
       <span style='color:#404040'>Disagree</span> | 
       <span style='color:#BFBFBF'>Neutral</span> |
       <span style='color:#1F497D'>Agree</span> | 
       <span style='color:#1F497D'>Strongly Agree</span>") +

  scale_fill_manual(values = cols) + 

  coord_flip() +
  
  theme(plot.title = element_markdown(size=18, hjust =-0.25),
        plot.subtitle = element_markdown(size=12,face="bold", color="#777B7E"),
        axis.title.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.y = element_text(color ="#777B7E", face="bold", size = 12),
        
        axis.title.x = element_markdown(hjust = 0,size = 12),
        axis.text.x = element_text(color ="#777B7E", face="bold", size = 12),
        axis.line.x = element_line(color="grey", size = 1),
        axis.ticks.x = element_line(color="#a9a9a9"),
        
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank())

Figure 2.19 100% stacked horizontal bar chart (Page 59)

ggsave("Figure 2.19.png", height = 4, width = 7,units = "in",dpi = 300)

Chapter three: Clutter is your enemy !

attributes <- c("Colleague recommendation",
"Previous work together",
"Affordability of services",
"National reputation",
"Local knowledge",
"Content expertise",
"Demonstration of results")
percent <- c(4,17,19,21,42,53,72)
feedback <- data.frame(attributes, percent)
library(gridExtra)
library(grid)
p1 <- ggplot(data = feedback, aes (x = reorder(attributes,percent), y = percent)) +
  geom_bar(stat = "identity")+
  geom_bar(data = feedback %>% 
             filter(attributes %in% c("Demonstration of results", 
                                      "Previous work together",
                                      "Affordability of services")),
           stat = "identity",
           fill ="black")+
  labs(title = "**Demonstring effectiveness**<span style = 'color:#404040'> is most important consideration<br>
  when selecting a provider</span> ",
  subtitle= "<span style = 'color:#404040'>In general,</span> 
  **what attributes are the most important** <br>
  <span style = 'color:#404040'>to you in selecting a service provider</span>",
  caption = "Data source: xyz; indluces N number of surbey respondents.\nNote that respondents were able to choose up to 3 options.") +
  scale_y_continuous(name = "% selecting given attribute", 
                     limits = c(0, 80),
                     breaks = seq(0, 80, by = 20),
                     labels = function(x) paste0(x,"%"),
                     position = 'right') +
  coord_flip() +
  theme(plot.title = element_markdown(size=18),
        plot.title.position = "plot",
        plot.subtitle = element_markdown(size=12, face="bold"),
        axis.title.y = element_blank(), 
        axis.ticks.y = element_blank(),
        axis.text.y = element_text(color ="#777B7E", face="bold", size = 12),
        axis.title.x = element_markdown(hjust = 0,size = 12, ),
        axis.text.x = element_text(color ="#777B7E", face="bold", size = 12),
        axis.line.x = element_line(color="grey", size = 1),
        axis.ticks.x = element_line(color="#a9a9a9"),
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank())


df <- tibble(
  label = c(
  "<span style='color:#000000'>Survey shows that **demonstation<br> 
  of results** is the single most<br>
  important dimension when<br>
  chosing a service provider</span>",
  "<span style='color:#000000'>**Affodability** and **exprerience** <br>
  **working together previously**,<br>
  which were hypothesis to be<br>
  very important in the decision<br>
  making process, were both cited<br>
  less frequently as important attributes.</span>"),
  x = c(0, 0),
  y = c(0.6, 0.2),
  hjust = c(0, 0),
  vjust = c(0.5, 0.5),
  color = c("white", "white"), # contour
  fill = c("white", "white")
)

p2 <- ggplot(df) +
  aes(x, y, 
      label = label, 
      color = color, 
      fill = fill,
      hjust = hjust, 
      vjust = vjust) +
  geom_richtext() +
  scale_color_identity() +
  scale_fill_identity() +
  xlim(0, 1) + ylim(0, 1) +
  theme(axis.title = element_blank(), # weird, why y here ?
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank())

grid.arrange(p1, p2,ncol= 2,widths = c(6.5,3))

Figure 3.14 Revamped summary of survey feedback

fig3.14 <- arrangeGrob(p1, p2, ncol= 2, widths = c(6.5,3)) 
ggsave(file="Figure 3.14 Revamped summary of survey feedback.png", fig3.14, height = 5, width = 10,units = "in",dpi = 300)

Chapter four: Focus on your audience’s attention

concern <- c("Engine power is less than expected",
"Tires make excessive noise while driving"  ,
"Engine makes abnormal/excessive noise",
"Seat material concerns",
"Excessive wind noise"  ,
"Hesitation or delay when shifting",
"Bluetooth system has poor sound quality",  
"Steering system/wheel has too much play",
"Bluetooth system is difficult to use",
"Front seat audio/entertainment/navigation controls")
number <- c(12.9,12.3,11.6,11.6,11.0,10.3,10.0,8.8,8.6,8.2)

design <- data.frame(concern, number)
p3 <- ggplot(data =design , aes (x = reorder(concern,number), y = number)) +
  geom_bar(stat = "identity",
           fill = "#7F7F7F")+
  
  geom_bar(data = design %>% 
             filter(concern %in% c("Tires make excessive noise while driving", 
                                      "Engine makes abnormal/excessive noise",
                                   "Excessive wind noise")),
           stat = "identity",
           fill = "#C0504D")+
  
  geom_bar(data = design %>% 
             filter(concern %in% c("Engine power is less than expected", 
                                     "Seat material concerns",
                                      "Hesitation or delay when shifting",
                                   "Bluetooth system has poor sound quality")),
           stat = "identity",
           fill ="#E6B9B8")+
  
  geom_text(aes(label =number),colour = "white", vjust = 0.5, hjust = 1.25) +
  
  
  labs(title = "Of the top design concerns, three are noise-related",
       subtitle = "Top 10 design concerns",
       y = "concerns per 1000") +
  
   scale_y_continuous(position = 'right') +
  
#Complaints about engine noise commonly cited after the car had not been driven for a while.

# Excessive wind noise is noted primarily in freeway driving at high speeds
  
  
  coord_flip() +
  
  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        plot.subtitle = element_markdown(size=12, face="bold"),
        
        axis.title.y = element_blank(), # weird, why y here ?
        axis.text.y = element_text(size = 12), 
        axis.ticks.y = element_blank(),
        
        axis.title.x = element_markdown(hjust = 0,size = 12),
        axis.text.x = element_blank(),
        axis.line.x = element_blank(),
        axis.ticks.x = element_blank(),
        #plot.margin = unit(c(1,6,1,1),"cm")
        plot.margin=unit(c(1,-0.5,1,1), "cm"),
        # legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank())



df2 <- tibble(
  label = c(
  "<span style='color:#000000'>Comments indicate that</span><br>
  <span style='color:#C0504D'>**noisy tire issues**</span><span style='color:#000000'> are</span><br>
  <span style='color:#000000'>most apparent **in the rain.**</span>",
  "<span style='color:#000000'>Complaints about</span><span style='color:#C0504D'> **engine**</span><br>
  <span style='color:#C0504D'>**noise**</span><span style='color:#000000'>commonly cited<br>
  **after the car had not<br>
  been driven for a while**.</span>",
  "<span style='color:#000000'>Excessive</span><span style='color:#C0504D'> **wind noise**</span>
  <span style='color:#000000'>is</span><br>
  <span style='color:#000000'>noted primarily in **freeway**<br>
  **driving ar high speeds**.</span>"),
  x = c(0, 0, 0),
  y = c(0.65, 0.4,0.25),
  hjust = c(0, 0,0),
  vjust = c(0, 0,0),
  color = c("white", "white", "white"), # contour
  fill = c("white", "white", "white")
)

p4 <- ggplot(df2) +
  aes(x, y, 
      label = label, 
      color = color, 
      fill = fill,
      hjust = hjust, 
      vjust = vjust) +
  geom_richtext() +
  scale_color_identity() +
  scale_fill_identity() +
  xlim(0, 1) + ylim(0, 1) +
  theme(axis.title = element_blank(), # weird, why y here ?
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank())

grid.arrange(p3, p4,ncol= 2, widths = c(12,4))

Figure 4.9 Create a visual hierarchy pf information

fig4.9 <- arrangeGrob(p3, p4, ncol= 2, widths = c(12,4)) 
ggsave(file="Figure 4.9 Create a visual hoerarchy of imformation.png", fig4.9, height = 5, width = 10,units = "in",dpi = 300)
ticket_wide <- read_csv("ticket.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   ticket_type = col_character(),
##   Jan = col_double(),
##   Feb = col_double(),
##   Mar = col_double(),
##   Apr = col_double(),
##   May = col_double(),
##   Jun = col_double(),
##   Jul = col_double(),
##   Aug = col_double(),
##   Sep = col_double(),
##   Oct = col_double(),
##   Nov = col_double(),
##   Dec = col_double()
## )
ticket <- ticket_wide %>% 
  pivot_longer(cols = !ticket_type, 
               names_to = "month", 
               values_to = "tickets") %>% 
  mutate(month = factor(month, levels = month.abb))
cols <- c("Processed" = "#1F497D",
          "Received" = "#7F7F7F")

ggplot(data=  ticket) +
  
  geom_line(aes(x= month, y = tickets, group = ticket_type, colour= ticket_type), size = 1.5) +
  
  geom_point(data = ticket %>% 
               filter(month %in% c("Aug","Sep","Oct","Nov","Dec")),
             aes(x= month, y = tickets, color = ticket_type, size = 1.5))+
  
  geom_text(aes(x = month, y = tickets, color = ticket_type, label = tickets), nudge_y = 20, size = 4,
            data = ticket %>% filter(month %in% c("Aug","Sep","Oct","Nov","Dec"), ticket_type == "Received")) +
  
  geom_text(aes(x = month, y = tickets, color = ticket_type, label = tickets), nudge_y = -20, size = 4,
            data = ticket %>% filter(month %in% c("Aug","Sep","Oct","Nov","Dec"), ticket_type == "Processed")) +
  
  #annotate("text", x = "Dec", y = 177, label = "Received", color = "#1F497D", hjust = 0, size = 4.5) + 
  # annotate("text", x = "Dec" , y = 140, label = "Processed", color ="#7F7F7F", hjust = 0, size = 4.5, fontface="bold") +
  
  scale_colour_manual(values = cols) +
  scale_y_continuous(expand =  c(0,0),
                     limits = c(0,300),
                     n.breaks = 7) +
    labs(title = "Ticket volume over time", 
         caption = "Data source: XYZ Dashboard, as of 12/31/2014 | A detailed analysis on tickets processed \nper person and time to resolve issues was undertaken to inform this request and can be provided.",
         x = "2014",
         y = "Number of tickets") +
  
  coord_cartesian(clip = 'off') + 

  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
       
        axis.text.y = element_text(size = 12), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.title.x= element_text(size = 12, hjust = 0, vjust = 0, color = "#6d6d6d"),
        
        axis.text.x = element_text(size = 12),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 12, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        
        axis.ticks = element_line(color="#a9a9a9") ,
      
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,2.5,0.5,0.5),"cm"))

Figure 4.14 Data labels used sparingly help draw attention

ggsave("Figure 4.14 Data labels used sparingly help draw attention.png", height = 5, width = 8,units = "in",dpi = 300)

Chapter five: think like a designer

grob_explanation <- grobTree(richtext_grob(
  "<span style='background-color:white'><b>2 employees quit in May.</b> We nearly kept up with<br>
  incoming bolume in the following two months, but fell<br>
  behind with the increase in Aug and haven't been able<br>
  to catch up since.</span>", 
  x=.375,  
  y = .90, 
  hjust=0, gp=gpar(col = "#6d6d6d", fontsize=11), 
  box_gp = gpar(col = "white", fill = "white"),
  padding = margin(0,0,0,0,"in")))

label1 <- grobTree(richtext_grob(
  "**Recieved**", 
  x= 1,  
  y = .62, 
  hjust = 0, gp=gpar(col = "#7F7F7F", fontsize = 12), 
  box_gp = gpar(col = "white", fill = "white"),
  padding = margin(0,0,0,0,"in")))

label2 <- grobTree(richtext_grob(
  "**Processed**", 
  x=1,  
  y = .48, 
  hjust=0, gp=gpar(col = "#1F497D", fontsize = 12), 
  box_gp = gpar(col = "white", fill = "white"),
  padding = margin(0,0,0,0,"in")))
cols <- c("Processed" = "#1F497D",
          "Received" = "#7F7F7F")

ggplot(data=  ticket) +
  geom_line(aes(x= month, y = tickets, group = ticket_type, colour= ticket_type), size = 1.5) +
  
  geom_point(data = ticket %>% 
               filter(month %in% c("Aug","Sep","Oct","Nov","Dec")),
             aes(x= month, y = tickets, color = ticket_type, size = 1.5))+
  
  geom_text(aes(x = month, y = tickets, color = ticket_type, label = tickets), nudge_y = 20, size = 4,
            data = ticket %>% filter(month %in% c("Aug","Sep","Oct","Nov","Dec"), ticket_type == "Received")) +
  
  geom_text(aes(x = month, y = tickets, color = ticket_type, label = tickets), nudge_y = -20, size = 4,
            data = ticket %>% filter(month %in% c("Aug","Sep","Oct","Nov","Dec"), ticket_type == "Processed")) +
  
  scale_colour_manual(values = cols) +
  scale_y_continuous(expand =  c(0,0),
                     limits = c(0,300),
                     n.breaks = 7) +
    labs(title = "Ticket volume over time", 
         caption = "Data source: XYZ Dashboard, as of 12/31/2014 | A detailed analysis on tickets processed \nper person and time to resolve issues was undertaken to inform this request and can be provided.",
         x = "2014",
         y = "Number of tickets") +
  
  coord_cartesian(clip = 'off') + 
  
  annotation_custom(grob_explanation) +
  annotation_custom(label1) +
  annotation_custom(label2) +
  annotate("segment", 
           x = 5, xend = 5, 
           y = 0, yend = 230,
           colour = "#7F7F7F") +
  theme(plot.title = element_markdown(size=16),
        plot.title.position = "plot",
        plot.caption = element_text(hjust = 0),
        plot.caption.position =  "plot",
       
        axis.text.y = element_text(size = 12), 
        axis.line.y = element_line(color = "#7F7F7F"),
        axis.title.x= element_text(size = 12, hjust = 0, vjust = 0, color = "#6d6d6d"),
        
        axis.text.x = element_text(size = 12),
        axis.line.x = element_line(color = "#7F7F7F"),
        axis.title.y = element_text(size = 12, hjust = 1 ,vjust = 2, color = "#6d6d6d"),
        
        axis.ticks = element_line(color="#a9a9a9") ,
      
        legend.position = "none",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(0.5,2.5,0.5,0.5),"cm"))

Figure 5.10 Add action title and annotation

ggsave("Figure 5.10 Add action title and annotation.png", height = 5, width = 8,units = "in",dpi = 300)
marriage_wide <- read_csv("marriage.csv")
## 
## -- Column specification --------------------------------------------------------
## cols(
##   education = col_character(),
##   `2008` = col_double(),
##   `2009` = col_double(),
##   `2010` = col_double(),
##   `2011` = col_double(),
##   `2012` = col_double()
## )
marriage_wide 
## # A tibble: 4 x 6
##   education                 `2008` `2009` `2010` `2011` `2012`
##   <chr>                      <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
## 1 Less than high school       26.8     25     23   23.2   23.4
## 2 High school graduate        35.9     34     31   30.5   30.1
## 3 Some college                42.5     41     37   36.7   36.5
## 4 Bachelor's degree or more   61.5     61     59   55     56.7
marriage <- marriage_wide %>%
  pivot_longer(cols = !education,
               names_to = "year",
               values_to = "rate")
marriage$education<- factor(marriage$education,levels=c("Less than high school","High school graduate", "Some college","Bachelor's degree or more"))
marriage$year <- as.numeric(marriage$year)
marriage
## # A tibble: 20 x 3
##    education                  year  rate
##    <fct>                     <dbl> <dbl>
##  1 Less than high school      2008  26.8
##  2 Less than high school      2009  25  
##  3 Less than high school      2010  23  
##  4 Less than high school      2011  23.2
##  5 Less than high school      2012  23.4
##  6 High school graduate       2008  35.9
##  7 High school graduate       2009  34  
##  8 High school graduate       2010  31  
##  9 High school graduate       2011  30.5
## 10 High school graduate       2012  30.1
## 11 Some college               2008  42.5
## 12 Some college               2009  41  
## 13 Some college               2010  37  
## 14 Some college               2011  36.7
## 15 Some college               2012  36.5
## 16 Bachelor's degree or more  2008  61.5
## 17 Bachelor's degree or more  2009  61  
## 18 Bachelor's degree or more  2010  59  
## 19 Bachelor's degree or more  2011  55  
## 20 Bachelor's degree or more  2012  56.7
grob_title <- grobTree(textGrob("New marriage rate by education", 
                                x=-.7,  y=1.1, hjust=0,
                                gp=gpar(fontsize=16)))

grob_subtitle <- grobTree(textGrob("Number of newly married adults per 1000 marriage eligible adults", 
                                   x=-.7,  y=1.03, hjust=0,
                                   gp=gpar(col = "#76787B", fontsize=14))) 

grob_caption <- grobTree(textGrob("Note: Marriage eligible includes the newly married plus those widowed,divorced\nor never married at interview\nSource: US Census\nAdapted from PEW RESEARCH CENTER", 
                                  x = -.7,  y = -.2, 
                                  hjust = 0,
                                  gp=gpar(col = "#76787B", fontsize=11))) 

ggplot()+
  geom_line(data = marriage,
            aes(x = year, y = rate, group = education),
            size= 2,
            color = "#A6A6A6") +

  geom_point(data= marriage %>% 
               filter(year == 2008 | year == 2012),
             aes(x= year, y= rate),
             color = "#A6A6A6",
             size = 6) +
  
  geom_line(data = marriage %>% 
                filter(education == "Bachelor's degree or more"),
            aes(x = year, y = rate, group = education),
            size= 2,
            color = "#FF3403") +
  geom_point(data= marriage %>% 
               filter(education == "Bachelor's degree or more" & (year == 2008 | year == 2012)),
             aes(x= year, y= rate),
             color = "#FF3403",
             size = 6)  +

  scale_y_continuous(limits = c(0,70)) +
  
  geom_text(data = filter(marriage, year== 2008),
            aes(x= year,y = rate, label=rate),
            nudge_x = -.5,
            color ="#76787B",
            size = 5) +
  geom_text(data= filter(marriage, year== 2012),
            aes(x= year,y = rate, label=rate),
            nudge_x = .5, 
            color ="#76787B",
            size = 5) +
  geom_text(data = filter(marriage, year== 2008,education == "Bachelor's degree or more"),
            aes(x= year,y = rate, label=rate),
            nudge_x = -.5,
            color ="#FF3403",
            size = 5) +
  geom_text(data= filter(marriage, year== 2012,education == "Bachelor's degree or more"),
            aes(x= year,y = rate, label=rate),
            nudge_x = .5, 
            color ="#FF3403",
            size = 5) +
  geom_text(data= filter(marriage, year == 2008),
            aes(x= year,y = rate,label=education),
            nudge_x = -1,
            hjust = 1,
            color ="#76787B",
            size = 5) +
  geom_text(data= filter(marriage, year == 2008, 
                         education == "Bachelor's degree or more"),
            aes(x= year,y = rate,label=education),
            nudge_x = -1,
            hjust = 1,
            color ="#FF3403",
            size = 5) +
  annotation_custom(grob_title) + 
  annotation_custom(grob_subtitle) + 
  annotation_custom(grob_caption)+
  
  coord_cartesian(clip = "off") +
  theme(plot.subtitle = element_text(color = "#76787B"),
        plot.title = element_text(hjust = -3),
        plot.caption = element_text(size = 8, color = "#76787B", hjust = 0, margin = margin(15,0,0,0, "pt")),
        axis.title.x =  element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(size = 12, color ="black"),
        axis.text.y = element_blank(),        
        axis.ticks.x = element_line(color="#a9a9a9"),
        axis.ticks.y = element_blank(),
        axis.line.x = element_line(color="grey", size = 1),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.margin = unit(c(2,1,3,7.5), "cm")) # margin(t = 2, r = 0, b = 0, l = 0, unit = "pt")

ggsave("Figure 5.4 Eliminate distractions.png", height = 6, width = 7,units = "in",dpi = 300)