Steven Ponce home pageSteven Ponce home page Steven Ponce
  • About
  • Data Visualizations
  • Projects
  • Behind the Viz
  • Resume
  • 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

Bob’s Burgers: Questioning Nature of Dialogue

  • Show All Code
  • Hide All Code

  • View Source

Questions dominate dialogue, with rare exceptions (highlighted). Red circles (○) indicate episodes where exclamations exceed questions

TidyTuesday
2024
Questions versus exclamations in Bob’s Burgers dialogue, highlighting episodes where exclamations win. Built in R.
Author

Steven Ponce

Published

November 18, 2024

Figure 1: Time series visualization showing the proportion of questions vs. exclamations in Bob’s Burgers dialogue across 14 seasons (2011-2024). Blue lines (questions) consistently trend higher than coral lines (exclamations), ranging 5-20%. Red circles highlight episodes where exclamations exceed questions.

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
    here,              # A Simpler Way to Find Your Files
    marquee            # Markdown Parser and Renderer for R Graphic
)    

### |- figure size ----
camcorder::gg_record(
  dir    = here::here("temp_plots"),
  device = "png",
  width  =  10,
  height =  10,
  units  = "in",
  dpi    = 320
)

### |- 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
#| warning: false

tt <- tidytuesdayR::tt_load(2024, week = 47) 

episode_metrics <- tt$episode_metrics|> clean_names() 

tidytuesdayR::readme(tt)
rm(tt)
```

3. Examine the Data

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

glimpse(episode_metrics)
skim(episode_metrics)
```

4. Tidy Data

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

### |- tidy data ----

### |- plot data ----

plot_data <- episode_metrics |>
  pivot_longer(
    cols = c(question_ratio, exclamation_ratio),
    names_to = "ratio_type", values_to = "value"
  ) |>
  mutate(
    ratio_type = case_when(
      ratio_type == "question_ratio" ~ "Questions",
      ratio_type == "exclamation_ratio" ~ "Exclamations"
    )
  )

### |- highlight data ----

highlight_data <- plot_data |>
  pivot_wider(names_from = ratio_type, values_from = value) |>
  filter(Exclamations > Questions)
```

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     <- "gray30"    
col_palette  <- c("Questions" = "#2171b5", "Exclamations" = "#ef8a62")

### |-  titles and caption ----
# icons
tt <- str_glue("#TidyTuesday: { 2024 } Week { 47 } &bull; Source: bobsburgersR R Package<br>")
li <- str_glue("<span style='font-family:fa6-brands'>&#xf08c;</span>")
gh <- str_glue("<span style='font-family:fa6-brands'>&#xf09b;</span>")
bs <- str_glue("<span style='font-family:fa6-brands'>&#xe671; </span>")

# text
title_text    <- str_glue("Bob's Burgers: Questioning Nature of Dialogue")

subtitle_text <- "Questions dominate dialogue (15-20%), with rare exceptions in early seasons (highlighted)\n\n
Red circles ({#FF0000 **○**}) indicate episodes where {#ef8a62 **_exclamations_**} exceed {#2171b5 **_questions_**}, more common in seasons 1-6"

caption_text  <- str_glue("{tt} {li} stevenponce &bull; {bs} sponce1 &bull; {gh} poncest &bull; #rstats #ggplot2")

### |-  fonts ----
font_add("fa6-brands", here::here("fonts/6.6.0/Font Awesome 6 Brands-Regular-400.otf"))
font_add_google("Oswald", regular.wt = 400, family = "title")
font_add_google("Source Sans Pro", family = "text")
font_add_google("Roboto Mono", family = "numbers")
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.6), color = text_col, family = "numbers"),
    axis.ticks.x          = element_line(color = text_col),
    axis.line.x           = element_line(color = "#252525", linewidth = .2),
    panel.grid.minor      = element_blank(),
    panel.grid.major      = element_blank(),
    panel.grid.major.y    = element_line(color = "grey90", linewidth = 0.2),
    panel.spacing.x       = unit(2, "lines"),
    panel.spacing.y       = unit(2, "lines"),
    strip.text            = element_text(size = rel(1), face = "bold", margin = margin(b = 10), family = "text"),
) 
```

6. Plot

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

### |-  plot ----
p <- plot_data |>
  ggplot(aes(x = episode, y = value * 100, color = ratio_type)) +

  # Geoms
  geom_line(aes(alpha = ratio_type), linewidth = 1) +
  geom_point(aes(alpha = ratio_type), size = 1.3) +
  geom_point(
    data = highlight_data,
    aes(y = Exclamations * 100),
    color = "red", size = 4, shape = 1, stroke = 0.8
  ) +

  # Scales
  scale_x_continuous() +
  scale_y_continuous(labels = scales::label_number(suffix = "%")) +
  scale_color_manual(values = col_palette) +
  scale_alpha_manual(values = c("Questions" = 1, "Exclamations" = 0.3)) +
  guides(alpha = "none") +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = "Episode Number",
    y = "Proportion of Total Sentences",
    color = "Sentence Type",
    title = title_text,
    subtitle = subtitle_text,
    caption = caption_text
  ) +

  # Facet
  facet_wrap(~season,
    labeller = label_both
  ) +

  # Theme
  theme(
    plot.title = element_text(
      size        = rel(2.3),
      family      = "title",
      face        = "bold",
      color       = title_col,
      margin      = margin(t = 5, b = 5)
    ),
    plot.subtitle = element_marquee(
      size        = rel(1.05),
      family      = "subtitle",
      color       = title_col,
      lineheight  = 1.1,
      margin      = margin(t = 5, b = 15)
    ),
    plot.caption = element_markdown(
      size        = rel(.65),
      family      = "caption",
      color       = caption_col,
      lineheight  = 0.65,
      hjust       = 0.5,
      halign      = 0.5,
      margin      = margin(t = 10, b = 5)
    ),
  )
```

7. Save

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

### |-  plot image ----  

# Save the plot as PNG
ggsave(
  filename = here::here("data_visualizations/TidyTuesday/2024/tt_2024_47.png"), 
  plot = p,
  width = 10, height = 10, units = "in", dpi = 320
)

### |-  plot thumbnail----
magick::image_read(here::here("data_visualizations/TidyTuesday/2024/tt_2024_47.png")) |>
  magick::image_resize(geometry = "400") |>
  magick::image_write(here::here("data_visualizations/TidyTuesday/2024/thumbnails/tt_2024_47.png"))
```

8. Session Info

TipExpand 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] marquee_0.1.0   here_1.0.1      glue_1.8.0      scales_1.3.0   
 [5] skimr_2.1.5     janitor_2.2.0   showtext_0.9-7  showtextdb_3.0 
 [9] sysfonts_0.8.9  ggtext_0.1.2    lubridate_1.9.3 forcats_1.0.0  
[13] stringr_1.5.1   dplyr_1.1.4     purrr_1.0.2     readr_2.1.5    
[17] tidyr_1.3.1     tibble_3.2.1    ggplot2_3.5.1   tidyverse_2.0.0
[21] pacman_0.5.1   

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

9. GitHub Repository

TipExpand for GitHub Repo

Access the GitHub repository here

Back to top
Source Code
---
freeze: true
title: "Bob's Burgers: Questioning Nature of Dialogue"
subtitle: "Questions dominate dialogue, with rare exceptions (highlighted). Red circles (○) indicate episodes where exclamations exceed questions"
author: "Steven Ponce"
description: "Questions versus exclamations in Bob's Burgers dialogue, highlighting episodes where exclamations win. Built in R."
date: "2024-11-18"
categories: ["TidyTuesday", "2024"]
image: "thumbnails/tt_2024_47.png"
format:
  html:
    toc: true
    toc-depth: 5
    code-link: true
    code-fold: true
    code-tools: true
    code-summary: "Show code"
editor_options: 
  
  chunk_output_type: inline
execute: 
  
  error: false
  message: false
  warning: false
  eval: true
# share:
#   permalink: "https://stevenponce.netlify.app/data_visualizations.png"
#   linkedin: true
#   twitter: true
#   email: true
---

![Time series visualization showing the proportion of questions vs. exclamations in Bob's Burgers dialogue across 14 seasons (2011-2024). Blue lines (questions) consistently trend higher than coral lines (exclamations), ranging 5-20%. Red circles highlight episodes where exclamations exceed questions.](tt_2024_47.png){#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
    here,              # A Simpler Way to Find Your Files
    marquee            # Markdown Parser and Renderer for R Graphic
)    

### |- figure size ----
camcorder::gg_record(
  dir    = here::here("temp_plots"),
  device = "png",
  width  =  10,
  height =  10,
  units  = "in",
  dpi    = 320
)

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

#### 2. Read in the Data 

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

tt <- tidytuesdayR::tt_load(2024, week = 47) 

episode_metrics <- tt$episode_metrics|> clean_names() 

tidytuesdayR::readme(tt)
rm(tt)
```

#### 3. Examine the Data

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

glimpse(episode_metrics)
skim(episode_metrics)
```

#### 4. Tidy Data 

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

### |- tidy data ----

### |- plot data ----

plot_data <- episode_metrics |>
  pivot_longer(
    cols = c(question_ratio, exclamation_ratio),
    names_to = "ratio_type", values_to = "value"
  ) |>
  mutate(
    ratio_type = case_when(
      ratio_type == "question_ratio" ~ "Questions",
      ratio_type == "exclamation_ratio" ~ "Exclamations"
    )
  )

### |- highlight data ----

highlight_data <- plot_data |>
  pivot_wider(names_from = ratio_type, values_from = value) |>
  filter(Exclamations > Questions)
```


#### 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     <- "gray30"    
col_palette  <- c("Questions" = "#2171b5", "Exclamations" = "#ef8a62")

### |-  titles and caption ----
# icons
tt <- str_glue("#TidyTuesday: { 2024 } Week { 47 } &bull; Source: bobsburgersR R Package<br>")
li <- str_glue("<span style='font-family:fa6-brands'>&#xf08c;</span>")
gh <- str_glue("<span style='font-family:fa6-brands'>&#xf09b;</span>")
bs <- str_glue("<span style='font-family:fa6-brands'>&#xe671; </span>")

# text
title_text    <- str_glue("Bob's Burgers: Questioning Nature of Dialogue")

subtitle_text <- "Questions dominate dialogue (15-20%), with rare exceptions in early seasons (highlighted)\n\n
Red circles ({#FF0000 **○**}) indicate episodes where {#ef8a62 **_exclamations_**} exceed {#2171b5 **_questions_**}, more common in seasons 1-6"

caption_text  <- str_glue("{tt} {li} stevenponce &bull; {bs} sponce1 &bull; {gh} poncest &bull; #rstats #ggplot2")

### |-  fonts ----
font_add("fa6-brands", here::here("fonts/6.6.0/Font Awesome 6 Brands-Regular-400.otf"))
font_add_google("Oswald", regular.wt = 400, family = "title")
font_add_google("Source Sans Pro", family = "text")
font_add_google("Roboto Mono", family = "numbers")
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.6), color = text_col, family = "numbers"),
    axis.ticks.x          = element_line(color = text_col),
    axis.line.x           = element_line(color = "#252525", linewidth = .2),
    panel.grid.minor      = element_blank(),
    panel.grid.major      = element_blank(),
    panel.grid.major.y    = element_line(color = "grey90", linewidth = 0.2),
    panel.spacing.x       = unit(2, "lines"),
    panel.spacing.y       = unit(2, "lines"),
    strip.text            = element_text(size = rel(1), face = "bold", margin = margin(b = 10), family = "text"),
) 
```


#### 6. Plot 

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

### |-  plot ----
p <- plot_data |>
  ggplot(aes(x = episode, y = value * 100, color = ratio_type)) +

  # Geoms
  geom_line(aes(alpha = ratio_type), linewidth = 1) +
  geom_point(aes(alpha = ratio_type), size = 1.3) +
  geom_point(
    data = highlight_data,
    aes(y = Exclamations * 100),
    color = "red", size = 4, shape = 1, stroke = 0.8
  ) +

  # Scales
  scale_x_continuous() +
  scale_y_continuous(labels = scales::label_number(suffix = "%")) +
  scale_color_manual(values = col_palette) +
  scale_alpha_manual(values = c("Questions" = 1, "Exclamations" = 0.3)) +
  guides(alpha = "none") +
  coord_cartesian(clip = "off") +

  # Labs
  labs(
    x = "Episode Number",
    y = "Proportion of Total Sentences",
    color = "Sentence Type",
    title = title_text,
    subtitle = subtitle_text,
    caption = caption_text
  ) +

  # Facet
  facet_wrap(~season,
    labeller = label_both
  ) +

  # Theme
  theme(
    plot.title = element_text(
      size        = rel(2.3),
      family      = "title",
      face        = "bold",
      color       = title_col,
      margin      = margin(t = 5, b = 5)
    ),
    plot.subtitle = element_marquee(
      size        = rel(1.05),
      family      = "subtitle",
      color       = title_col,
      lineheight  = 1.1,
      margin      = margin(t = 5, b = 15)
    ),
    plot.caption = element_markdown(
      size        = rel(.65),
      family      = "caption",
      color       = caption_col,
      lineheight  = 0.65,
      hjust       = 0.5,
      halign      = 0.5,
      margin      = margin(t = 10, b = 5)
    ),
  )
```



#### 7. Save

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

### |-  plot image ----  

# Save the plot as PNG
ggsave(
  filename = here::here("data_visualizations/TidyTuesday/2024/tt_2024_47.png"), 
  plot = p,
  width = 10, height = 10, units = "in", dpi = 320
)

### |-  plot thumbnail----
magick::image_read(here::here("data_visualizations/TidyTuesday/2024/tt_2024_47.png")) |>
  magick::image_resize(geometry = "400") |>
  magick::image_write(here::here("data_visualizations/TidyTuesday/2024/thumbnails/tt_2024_47.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–2026 Steven Ponce · Built with R + Quarto

Source Issues