Introductionn

This project shows the visualization of Breaking Bad series data using Waffle Chart

# Import the libraries
library(tidyverse) # For data transformation and manipulation
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2) # For data visualisation
library(tidyverse)
library(showtext)
## Loading required package: sysfonts
## Loading required package: showtextdb
library(ggtext)
library(waffle) # For data visualisation
library(MetBrewer)
library(patchwork)

Loading data into R Environment

# Load the data
path = "C:/Users/Hp/Desktop/IBK - TEMP/Breaking Bad Dataset.csv"

breaking_bad <- read_csv(path) 
## Rows: 63 Columns: 8
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): Release_date, Title, US_views_millions, Director
## dbl (4): Season, Episode, Duration_minutes, IMDB_rating
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
###### Exploratory Data Analysis

# Check the first few rows of the data
head(breaking_bad)
## # A tibble: 6 × 8
##   Release_date Season Episode Title           Duration_minutes US_views_millions
##   <chr>         <dbl>   <dbl> <chr>                      <dbl> <chr>            
## 1 20-Jan-08         1       1 Pilot                         58 1.41             
## 2 27-Jan-08         1       2 Cat's in the B…               48 1.49             
## 3 10-Feb-08         1       3 ...And the Bag…               48 1.08             
## 4 17-Feb-08         1       4 Cancer Man                    48 1.09             
## 5 24-Feb-08         1       5 Gray Matter                   48 0.97             
## 6 2-Mar-08          1       6 Crazy Handful …               48 1.07             
## # ℹ 2 more variables: IMDB_rating <dbl>, Director <chr>
# Check the no. of rows and columns of the data
dim(breaking_bad)
## [1] 63  8
# Check information of the data
glimpse(breaking_bad)
## Rows: 63
## Columns: 8
## $ Release_date      <chr> "20-Jan-08", "27-Jan-08", "10-Feb-08", "17-Feb-08", …
## $ Season            <dbl> 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2…
## $ Episode           <dbl> 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, …
## $ Title             <chr> "Pilot", "Cat's in the Bag...", "...And the Bag's in…
## $ Duration_minutes  <dbl> 58, 48, 48, 48, 48, 48, 48, 47, 46, 47, 47, 47, 47, …
## $ US_views_millions <chr> "1.41", "1.49", "1.08", "1.09", "0.97", "1.07", "1.5…
## $ IMDB_rating       <dbl> 9.0, 8.6, 8.7, 8.2, 8.3, 9.3, 8.8, 8.6, 9.3, 8.3, 8.…
## $ Director          <chr> "Vince Gilligan", "Adam Bernstein", "Adam Bernstein"…

Data Preparation

df <- breaking_bad|> 
  select(c(Season,Episode,Duration_minutes))|> group_by(Season,Episode)|>
  summarise(duration = sum(Duration_minutes))
## `summarise()` has grouped output by 'Season'. You can override using the
## `.groups` argument.
df
## # A tibble: 63 × 3
## # Groups:   Season [6]
##    Season Episode duration
##     <dbl>   <dbl>    <dbl>
##  1      1       1       58
##  2      1       2       48
##  3      1       3       48
##  4      1       4       48
##  5      1       5       48
##  6      1       6       48
##  7      1       7       48
##  8      2       1       47
##  9      2       2       46
## 10      2       3       47
## # ℹ 53 more rows
df<- df|>as.data.frame()

df
##    Season Episode duration
## 1       1       1       58
## 2       1       2       48
## 3       1       3       48
## 4       1       4       48
## 5       1       5       48
## 6       1       6       48
## 7       1       7       48
## 8       2       1       47
## 9       2       2       46
## 10      2       3       47
## 11      2       4       47
## 12      2       5       47
## 13      2       6       47
## 14      2       7       47
## 15      2       8       47
## 16      2       9       47
## 17      2      10       47
## 18      2      11       47
## 19      2      12       47
## 20      2      13       48
## 21      3       1       47
## 22      3       2       47
## 23      3       3       47
## 24      3       4       47
## 25      3       5       47
## 26      3       6       47
## 27      3       7       47
## 28      3       8       47
## 29      3       9       47
## 30      3      10       47
## 31      3      11       47
## 32      3      12       47
## 33      3      13       47
## 34      4       1       48
## 35      4       2       60
## 36      4       3       47
## 37      4       4       47
## 38      4       5       47
## 39      4       6       47
## 40      4       7       47
## 41      4       8       47
## 42      4       9       47
## 43      4      10       47
## 44      4      11       45
## 45      4      12       47
## 46      4      13       51
## 47      5       1       43
## 48      5       2       48
## 49      5       3       48
## 50      5       4       48
## 51      5       5       48
## 52      5       6       48
## 53      5       7       48
## 54      5       8       48
## 55      5       9       48
## 56      5      10       48
## 57      5      11       48
## 58      5      12       48
## 59      5      13       47
## 60      5      14       48
## 61      5      15       55
## 62      5      16       55
## 63     NA      NA      776

Text Preparation

font_add_google("Outfit", "title_font")
font_add_google("Cabin", "body_font")
showtext_auto()

title_font <- "title_font"
body_font <- "body_font"

Data Visualization

graph = ggplot(df, aes(fill = Season, values = duration)) +
   geom_waffle(color = "white", size = 0.25, n_rows = 10, flip = TRUE) +
  facet_wrap(~Episode, nrow = 1, strip.position = "bottom") +
  scale_x_discrete() + 
  scale_y_continuous(labels = function(x) x * 10, # make this multiply the same as n_rows
                     expand = c(0,0))+
  scale_fill_met_d("VanGogh2", direction=1)+
  labs(title = "Breaking Bad Series had a total of 5 Seasons", x = "Episodes", y="Duration in Minutes",
       
       subtitle =  "Season 1 had the lowest episodes:7\nSeason 5 had the highest episodes:16\nSeason 5 ran for the highest number of minutes:  776 minutes\nBoth seasons 2 and 3 ran for exactly the same number of minutes: 611 minutes",
       caption = "Graphic: Ibikunle Gabriel|Data Source: Kaggle")+
  theme_minimal()+
  theme(
        axis.text.x = element_text(family = body_font, size=12),
    axis.text.y = element_text(family = body_font, size=12),
  # Legend
  legend.position = "right",
  legend.title = element_text("Season"),
  legend.spacing = unit(0.5, 'cm'),
  legend.key.height= unit(0.5, 'cm'),
  legend.key.width= unit(0.7, 'cm'),
  legend.text = element_text(family = body_font,
                             size=13,
                             face = 'plain',
                             color = "grey10"),
  
  # TITLE
  plot.title.position = "plot",
  plot.title = element_textbox(margin = margin(20, 0, 10, 0),
                               size = 30,
                               family = title_font,
                               face = "bold",
                               width = unit(55, "lines")),
  
  # SUB-TITLE
  plot.subtitle = element_text(margin = margin(10, 0, 20, 0),
                            size = 16,
                            family = body_font,
                            color = "grey15"),
  # Caption
  plot.caption.position = "plot", 
  plot.caption = element_text(family=body_font,
                              face="bold",
                              size=16, 
                              color="grey40",
                              hjust=.5, 
                              margin=margin(20,0,0,0)),
  
  plot.background = element_rect(color="white", fill="white"),
  plot.margin = margin(20, 40, 20, 40)
)

showtext_opts(dpi = 320)
ggsave(
  "C:/Users/Hp/Desktop/IBK - TEMP/breaking_bad.png", 
  dpi=320, width = 12, height = 9
)
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family 'Season' not found, will use 'sans' instead
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family 'Season' not found, will use 'sans' instead
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family 'Season' not found, will use 'sans' instead
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family 'Season' not found, will use 'sans' instead
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family 'Season' not found, will use 'sans' instead
showtext_auto(FALSE)
 
graph
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database