• Steven Ponce
  • About
  • Data Visualizations
  • Projects
  • Email

On this page

  • Steps to Create this Graphic
    • 1. Load Packages & Setup
    • 2. Read in the Data
    • 3. Examine the Data
    • 4. Tidy Data
    • 5. Visualization Parameters
    • 6. Plot
    • 7. Save
    • 8. Session Info
    • 9. GitHub Repository

The Rise and Fall of Bob’s Burgers Ratings Across Seasons

  • Show All Code
  • Hide All Code

  • View Source

An exploration of how episode and season ratings fluctuate over the course of 14 seasons.

Bob's Burgers
Standalone
2024
Author

Steven Ponce

Published

October 27, 2024

Figure 1: Line chart and heatmap showing IMDb ratings for Bob’s Burgers across seasons and episodes.

Steps to Create this Graphic

1. Load Packages & Setup

Show code
```{r}
#| label: load
#| warning: false

## 1. LOAD PACKAGES & SETUP ----
if (!require("pacman")) install.packages("pacman")
pacman::p_load(
  tidyverse,         # Easily Install and Load the 'Tidyverse'
  ggtext,            # Improved Text Rendering Support for 'ggplot2'
  showtext,          # Using Fonts More Easily in R Graphs
  janitor,           # Simple Tools for Examining and Cleaning Dirty Data
  skimr,             # Compact and Flexible Summaries of Data
  scales,            # Scale Functions for Visualization
  glue,              # Interpreted String Literals
  colorspace,        # A Toolbox for Manipulating and Assessing Colors and Palettes
  patchwork,         # The Composer of Plots
  bobsburgersR       # Bob's Burgers Datasets for Data Visualization
)  

### |- resolution ----
showtext_opts(dpi = 320, regular.wt = 300, bold.wt = 800)
```

2. Read in the Data

Show code
```{r}
#| label: read
#| include: true
#| eval: true
#| results: 'hide'
#| warning: false

bobsburgersR::imdb_wikipedia_data
```

3. Examine the Data

Show code
```{r}
#| label: examine
#| include: true
#| eval: true
#| results: 'hide'
#| warning: false

glimpse(imdb_wikipedia_data)
skim(imdb_wikipedia_data)
```

4. Tidy Data

Show code
```{r}
#| label: tidy
#| warning: false

### |- heatmap data ----
heatmap_data <- imdb_wikipedia_data |>
  mutate(
    season = factor(season),
    episode = factor(episode, levels = rev(unique(episode))),
  ) |>
  filter(!is.na(rating))

### |- heatmap data ----
linechart_data <- imdb_wikipedia_data |>
  group_by(season) |>
  summarize(
    median_rating = median(rating, na.rm = TRUE),
    .groups = "drop"
  ) |>
  mutate(season = factor(season))
```

5. Visualization Parameters

Show code
```{r}
#| label: params
#| include: true
#| warning: false

### |- plot aesthetics ----
bkg_col      <- "#f5f5f2"    
title_col    <- "gray20"           
subtitle_col <- "gray20"     
caption_col  <- "gray30"   
text_col     <- "gray20"    
col_palette  <- c("#F9F6FB", "#F0DDF1", "#D6B9E3", "#B78FCA", "#9D5CAA", "#684671")

### |-  titles and caption ----

# icons
tt <- str_glue("Source: {{bobsburgersR}}")
li <- str_glue("<span style='font-family:fa6-brands'>&#xf08c;</span>")
gh <- str_glue("<span style='font-family:fa6-brands'>&#xf09b;</span>")

# text
title_text    <- str_glue("The Rise and Fall of Bob's Burgers Ratings Across Seasons")
subtitle_text <- str_glue("An exploration of how episode and season ratings fluctuate over the course of 14 seasons.")
caption_text  <- str_glue("{li} stevenponce &bull; {gh} poncest &bull; #rstats #ggplot2 &bull; {tt}")

### |-  fonts ----
font_add("fa6-brands", here::here("fonts/6.4.2/Font Awesome 6 Brands-Regular-400.otf"))
font_add_google("Oswald", regular.wt = 400, family = "title")
font_add_google("Merriweather Sans", regular.wt = 400, family = "subtitle")
font_add_google("Merriweather Sans", regular.wt = 400, family = "text")
font_add_google("Noto Sans", regular.wt = 400, family = "caption")
showtext_auto(enable = TRUE)

### |-  plot theme ----
theme_set(theme_minimal(base_size = 14, base_family = "text"))                

theme_update(
  plot.title.position   = "plot",
  plot.caption.position = "plot",
  legend.position       = 'plot',
  plot.background       = element_rect(fill = bkg_col, color = bkg_col),
  panel.background      = element_rect(fill = bkg_col, color = bkg_col),
  plot.margin           = margin(t = 10, r = 20, b = 10, l = 20),
  axis.title.x          = element_text(margin = margin(10, 0, 0, 0), size = rel(1.1), 
                                       color = text_col, family = "text", face = "bold", hjust = 0.5),
  axis.title.y          = element_text(margin = margin(0, 10, 0, 0), size = rel(1.1), 
                                       color = text_col, family = "text", face = "bold", hjust = 0.5),
  axis.text             = element_text(size = rel(0.8), color = text_col, family = "text"),
  panel.grid.major.y    = element_line(color = "#d3d3d3", linewidth = 0.5), 
  panel.grid.major.x    = element_blank(), 
  panel.grid.minor      = element_blank()
)  
```

6. Plot

Show code
```{r}
#| label: plot
#| warning: false

### |-  line chart ----
line_chart <- linechart_data |>
  ggplot(aes(x = season, y = median_rating, group = 1)) +

  # Geoms
  geom_step(color = "#6a1b9a", linewidth = 1.5) +
  geom_point(color = "#8e24aa", size = 4, shape = 20) +
  geom_text(aes(label = format(round(median_rating, 1), nsmall = 1)),
    hjust = -0.2, vjust = -0.8, size = 4.5, color = "#6a1b9a", fontface = "bold"
  ) +

  # Scales
  scale_x_discrete() +
  scale_y_continuous(
    labels = scales::label_number(accuracy = 0.1),
    expand = expansion(mult = c(0, 0.05))
  ) +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = NULL,
    y = "Median IMDb Rating",
  ) +

  # Theme
  theme(
    axis.text.x = element_blank()
  )


### |-  heatmap plot ----
heatmap_plot <- heatmap_data |>
  ggplot(aes(x = season, y = episode, fill = rating)) +

  # Geoms
  geom_tile(linewidth = 0.25, color = "grey20") +
  geom_text(aes(label = round(rating, 1)),
    color = "black",
    size = 3,
    fontface = "bold"
  ) +

  # Scales
  scale_x_discrete(position = "top") +
  scale_y_discrete() +
  scale_fill_stepsn(
    colors = col_palette,
    breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
    transform = "identity",
    guide = guide_colorsteps(
      barheight = unit(20, "lines"),
      barwidth = unit(.75, "lines")
    )
  ) +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = "Season",
    y = "Episode",
  ) +

  # Theme
  theme(
    legend.position    = "right",
    legend.title       = element_text(size = 10, face = "bold"),
    legend.text        = element_text(size = 8),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    panel.grid         = element_blank(),
  )


### |-  combined plots ----  
combined_plot <- (line_chart / heatmap_plot) +
  patchwork::plot_layout(
    heights = c(0.5, 1.25),
  ) +

  # Labs
  plot_annotation(
    title = title_text,
    subtitle = subtitle_text,
    caption = caption_text
  ) &

  # Theme
  theme(
    plot.margin  = margin(10, 20, 10, 20),
    plot.title   = element_markdown(
      size       = rel(1.5),
      family     = "title",
      face       = "bold",
      color      = title_col,
      lineheight = 1.1,
      margin     = margin(t = 10, b = 5)
    ),
    plot.subtitle = element_markdown(
      size       = rel(0.85),
      family     = "subtitle",
      color      = subtitle_col,
      lineheight = 1.1,
      margin     = margin(t = 5, b = 15)
    ),
    plot.caption = element_markdown(
      size       = rel(0.65),
      family     = "caption",
      color      = caption_col,
      lineheight = 1.1,
      hjust      = 0.5,
      halign     = 0.5,
      margin     = margin(t = 5, b = 5)
    )
  )
```

7. Save

Show code
```{r}
#| label: save
#| warning: false

### |-  plot image ----  

# Save the plot as PNG
ggsave(
  filename = here::here("projects/standalone_visualizations/sa_2024-10-27.png"), 
  plot = combined_plot,
  width = 8, height = 12, units = "in", dpi = 320
)

### |-  plot thumbnail----  
magick::image_read(here::here("projects/standalone_visualizations/sa_2024-10-27.png")) |> 
  magick::image_resize(geometry = "400") |> 
  magick::image_write(here::here("projects/standalone_visualizations/thumbnails/sa_2024-10-27.png"))
```

8. Session Info

Expand for Session Info
R version 4.4.1 (2024-06-14 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 22631)

Matrix products: default


locale:
[1] LC_COLLATE=English_United States.utf8 
[2] LC_CTYPE=English_United States.utf8   
[3] LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] bobsburgersR_0.0.0.9000 patchwork_1.3.0         colorspace_2.1-1       
 [4] glue_1.8.0              scales_1.3.0            skimr_2.1.5            
 [7] janitor_2.2.0           showtext_0.9-7          showtextdb_3.0         
[10] sysfonts_0.8.9          ggtext_0.1.2            lubridate_1.9.3        
[13] forcats_1.0.0           stringr_1.5.1           dplyr_1.1.4            
[16] purrr_1.0.2             readr_2.1.5             tidyr_1.3.1            
[19] tibble_3.2.1            ggplot2_3.5.1           tidyverse_2.0.0        
[22] pacman_0.5.1           

loaded via a namespace (and not attached):
 [1] gtable_0.3.6      xfun_0.49         htmlwidgets_1.6.4 tzdb_0.5.0       
 [5] vctrs_0.6.5       tools_4.4.0       generics_0.1.3    curl_6.0.0       
 [9] fansi_1.0.6       pkgconfig_2.0.3   lifecycle_1.0.4   compiler_4.4.0   
[13] farver_2.1.2      textshaping_0.4.0 munsell_0.5.1     repr_1.1.7       
[17] codetools_0.2-20  snakecase_0.11.1  htmltools_0.5.8.1 yaml_2.3.10      
[21] pillar_1.9.0      magick_2.8.5      commonmark_1.9.2  tidyselect_1.2.1 
[25] digest_0.6.37     stringi_1.8.4     labeling_0.4.3    rprojroot_2.0.4  
[29] fastmap_1.2.0     grid_4.4.0        here_1.0.1        cli_3.6.4        
[33] magrittr_2.0.3    base64enc_0.1-3   utf8_1.2.4        withr_3.0.2      
[37] timechange_0.3.0  rmarkdown_2.29    ragg_1.3.3        hms_1.1.3        
[41] evaluate_1.0.1    knitr_1.49        markdown_1.13     rlang_1.1.6      
[45] gridtext_0.1.5    Rcpp_1.0.13-1     xml2_1.3.6        renv_1.0.3       
[49] rstudioapi_0.17.1 jsonlite_1.8.9    R6_2.5.1          systemfonts_1.1.0

9. GitHub Repository

Expand for GitHub Repo

Access the GitHub repository here

Back to top
Source Code
---
title: "The Rise and Fall of Bob's Burgers Ratings Across Seasons"
subtitle: "An exploration of how episode and season ratings fluctuate over the course of 14 seasons."
author: "Steven Ponce"
date: "2024-10-27"
categories: ["Bob's Burgers", "Standalone", "2024"]
image: "thumbnails/sa_2024-10-27.png"
format:
  html:
    toc: true
    toc-depth: 5
    code-link: true
    code-fold: true
    code-tools: true
    code-summary: "Show code"
    self-contained: true
editor_options: 
  
  chunk_output_type: inline
execute: 
  
  error: false
  message: false
  warning: false
  eval: true
# share:
#   permalink: "https://stevenponce.netlify.app/projects.html"
#   linkedin: true
#   twitter: true
#   email: true
---

![Line chart and heatmap showing IMDb ratings for Bob's Burgers across seasons and episodes.](sa_2024-10-27){#fig-1}

### <mark> __Steps to Create this Graphic__ </mark>

#### 1. Load Packages & Setup 

```{r}
#| label: load
#| warning: false

## 1. LOAD PACKAGES & SETUP ----
if (!require("pacman")) install.packages("pacman")
pacman::p_load(
  tidyverse,         # Easily Install and Load the 'Tidyverse'
  ggtext,            # Improved Text Rendering Support for 'ggplot2'
  showtext,          # Using Fonts More Easily in R Graphs
  janitor,           # Simple Tools for Examining and Cleaning Dirty Data
  skimr,             # Compact and Flexible Summaries of Data
  scales,            # Scale Functions for Visualization
  glue,              # Interpreted String Literals
  colorspace,        # A Toolbox for Manipulating and Assessing Colors and Palettes
  patchwork,         # The Composer of Plots
  bobsburgersR       # Bob's Burgers Datasets for Data Visualization
)  

### |- resolution ----
showtext_opts(dpi = 320, regular.wt = 300, bold.wt = 800)
```

#### 2. Read in the Data 

```{r}
#| label: read
#| include: true
#| eval: true
#| results: 'hide'
#| warning: false

bobsburgersR::imdb_wikipedia_data
```

#### 3. Examine the Data

```{r}
#| label: examine
#| include: true
#| eval: true
#| results: 'hide'
#| warning: false

glimpse(imdb_wikipedia_data)
skim(imdb_wikipedia_data)
```

#### 4. Tidy Data 

```{r}
#| label: tidy
#| warning: false

### |- heatmap data ----
heatmap_data <- imdb_wikipedia_data |>
  mutate(
    season = factor(season),
    episode = factor(episode, levels = rev(unique(episode))),
  ) |>
  filter(!is.na(rating))

### |- heatmap data ----
linechart_data <- imdb_wikipedia_data |>
  group_by(season) |>
  summarize(
    median_rating = median(rating, na.rm = TRUE),
    .groups = "drop"
  ) |>
  mutate(season = factor(season))
```


#### 5. Visualization Parameters 

```{r}
#| label: params
#| include: true
#| warning: false

### |- plot aesthetics ----
bkg_col      <- "#f5f5f2"    
title_col    <- "gray20"           
subtitle_col <- "gray20"     
caption_col  <- "gray30"   
text_col     <- "gray20"    
col_palette  <- c("#F9F6FB", "#F0DDF1", "#D6B9E3", "#B78FCA", "#9D5CAA", "#684671")

### |-  titles and caption ----

# icons
tt <- str_glue("Source: {{bobsburgersR}}")
li <- str_glue("<span style='font-family:fa6-brands'>&#xf08c;</span>")
gh <- str_glue("<span style='font-family:fa6-brands'>&#xf09b;</span>")

# text
title_text    <- str_glue("The Rise and Fall of Bob's Burgers Ratings Across Seasons")
subtitle_text <- str_glue("An exploration of how episode and season ratings fluctuate over the course of 14 seasons.")
caption_text  <- str_glue("{li} stevenponce &bull; {gh} poncest &bull; #rstats #ggplot2 &bull; {tt}")

### |-  fonts ----
font_add("fa6-brands", here::here("fonts/6.4.2/Font Awesome 6 Brands-Regular-400.otf"))
font_add_google("Oswald", regular.wt = 400, family = "title")
font_add_google("Merriweather Sans", regular.wt = 400, family = "subtitle")
font_add_google("Merriweather Sans", regular.wt = 400, family = "text")
font_add_google("Noto Sans", regular.wt = 400, family = "caption")
showtext_auto(enable = TRUE)

### |-  plot theme ----
theme_set(theme_minimal(base_size = 14, base_family = "text"))                

theme_update(
  plot.title.position   = "plot",
  plot.caption.position = "plot",
  legend.position       = 'plot',
  plot.background       = element_rect(fill = bkg_col, color = bkg_col),
  panel.background      = element_rect(fill = bkg_col, color = bkg_col),
  plot.margin           = margin(t = 10, r = 20, b = 10, l = 20),
  axis.title.x          = element_text(margin = margin(10, 0, 0, 0), size = rel(1.1), 
                                       color = text_col, family = "text", face = "bold", hjust = 0.5),
  axis.title.y          = element_text(margin = margin(0, 10, 0, 0), size = rel(1.1), 
                                       color = text_col, family = "text", face = "bold", hjust = 0.5),
  axis.text             = element_text(size = rel(0.8), color = text_col, family = "text"),
  panel.grid.major.y    = element_line(color = "#d3d3d3", linewidth = 0.5), 
  panel.grid.major.x    = element_blank(), 
  panel.grid.minor      = element_blank()
)  
```


#### 6. Plot 

```{r}
#| label: plot
#| warning: false

### |-  line chart ----
line_chart <- linechart_data |>
  ggplot(aes(x = season, y = median_rating, group = 1)) +

  # Geoms
  geom_step(color = "#6a1b9a", linewidth = 1.5) +
  geom_point(color = "#8e24aa", size = 4, shape = 20) +
  geom_text(aes(label = format(round(median_rating, 1), nsmall = 1)),
    hjust = -0.2, vjust = -0.8, size = 4.5, color = "#6a1b9a", fontface = "bold"
  ) +

  # Scales
  scale_x_discrete() +
  scale_y_continuous(
    labels = scales::label_number(accuracy = 0.1),
    expand = expansion(mult = c(0, 0.05))
  ) +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = NULL,
    y = "Median IMDb Rating",
  ) +

  # Theme
  theme(
    axis.text.x = element_blank()
  )


### |-  heatmap plot ----
heatmap_plot <- heatmap_data |>
  ggplot(aes(x = season, y = episode, fill = rating)) +

  # Geoms
  geom_tile(linewidth = 0.25, color = "grey20") +
  geom_text(aes(label = round(rating, 1)),
    color = "black",
    size = 3,
    fontface = "bold"
  ) +

  # Scales
  scale_x_discrete(position = "top") +
  scale_y_discrete() +
  scale_fill_stepsn(
    colors = col_palette,
    breaks = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
    transform = "identity",
    guide = guide_colorsteps(
      barheight = unit(20, "lines"),
      barwidth = unit(.75, "lines")
    )
  ) +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = "Season",
    y = "Episode",
  ) +

  # Theme
  theme(
    legend.position    = "right",
    legend.title       = element_text(size = 10, face = "bold"),
    legend.text        = element_text(size = 8),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    panel.grid         = element_blank(),
  )


### |-  combined plots ----  
combined_plot <- (line_chart / heatmap_plot) +
  patchwork::plot_layout(
    heights = c(0.5, 1.25),
  ) +

  # Labs
  plot_annotation(
    title = title_text,
    subtitle = subtitle_text,
    caption = caption_text
  ) &

  # Theme
  theme(
    plot.margin  = margin(10, 20, 10, 20),
    plot.title   = element_markdown(
      size       = rel(1.5),
      family     = "title",
      face       = "bold",
      color      = title_col,
      lineheight = 1.1,
      margin     = margin(t = 10, b = 5)
    ),
    plot.subtitle = element_markdown(
      size       = rel(0.85),
      family     = "subtitle",
      color      = subtitle_col,
      lineheight = 1.1,
      margin     = margin(t = 5, b = 15)
    ),
    plot.caption = element_markdown(
      size       = rel(0.65),
      family     = "caption",
      color      = caption_col,
      lineheight = 1.1,
      hjust      = 0.5,
      halign     = 0.5,
      margin     = margin(t = 5, b = 5)
    )
  )

```



#### 7. Save

```{r}
#| label: save
#| warning: false

### |-  plot image ----  

# Save the plot as PNG
ggsave(
  filename = here::here("projects/standalone_visualizations/sa_2024-10-27.png"), 
  plot = combined_plot,
  width = 8, height = 12, units = "in", dpi = 320
)

### |-  plot thumbnail----  
magick::image_read(here::here("projects/standalone_visualizations/sa_2024-10-27.png")) |> 
  magick::image_resize(geometry = "400") |> 
  magick::image_write(here::here("projects/standalone_visualizations/thumbnails/sa_2024-10-27.png"))
```



#### 8. Session Info

::: {.callout-tip collapse="true"}
##### Expand for Session Info

```{r, echo = FALSE}
#| eval: true
#| warning: false

sessionInfo()
```
:::

#### 9. GitHub Repository

::: {.callout-tip collapse="true"}

##### Expand for GitHub Repo
 
[Access the GitHub repository here](https://github.com/poncest/personal-website/)
:::

© 2024 Steven Ponce

Source Issues