Flipbookr with Quarto

Kieran Healy

2023-08-10

Flipbookr

  • {{flipbookr}} is an R package written by Gina Reynolds. It’s very useful for teaching. It was developed for use with .Rmd files Xaringan and presently does not work with Quarto.

  • I hacked-up a version of Flipbookr that does work with Quarto. Use with Xarginan should be exactly the same as before.

  • Right now it’s incomplete. I’ve just focused on getting the main user-facing function, chunk_reveal() to work. But this is also most of what the package does.

Install

Setup

# install.packages("socviz") ## If needed
library(tidyverse)
library(socviz)

library(flipbookr)

The first two packages are just for data and code used on these slides; they aren’t required for flipbookr

Main changes

  • chunk_reveal() can take several new arguments. These are:
  • platform = c("xaringan", "quarto")
    • Defaults to xaringan, so older code/docs should work unchanged.
  • lcolw and rcolw: left and right column widths
    • Given as characters, e.g. "40" and interpreted as percentages. Defaults to “40” left and “60” right
    • These are needed because Quarto handles column markup differently from Xaringan,
    • These arguments do nothing in the xaringan case
  • smallcode Logical, defaults to FALSE.
    • If TRUE then inserts a .smallcode class name in outputted code blocks.
    • No CSS is added in the package right now. Your theme or your custom.scss file needs to define a behavior (e.g. font-size: 0.75em) for this class for it to have any effect.

Use

  • Same as before but with chunk_reveal(platform = "quarto") for Quarto docs.
  • Convenience function chunkq_reveal() sets the platform to quarto without you having to specify it every time (q for quarto)
  • chunq_reveal() is presently unexported, so use ::: instead of :: to grab it.

Limitations

  • The main thing not supported from chunk_reveal() at present is layouts with more than two columns.
  • Line highlighting in Quarto works differently from Xaringan. Chunks will auto-highlight properly (in the Quarto style) as each new line or group of lines is revealed, but right now you can’t use #<< to pick out arbitrary lines.
  • I think it’d be possible (and probably better) to write a Quarto Lua extension to do this rather than trying to build it in to the flipbookr package directly
  • Right now you can’t pass in Quarto’s line-highlighting syntax for code cells either, so things like code-line-numbers="6-8" won’t work.(Should be possible to add this though.)

Things that should still work

  • Stepping through code as usual
  • #BREAK
  • #ROTATE
  • Use of multiple realizations

Flipbookr Runthrough

We’re going to run this code:

#| label: flipbookexample
#| echo: false
#| eval: false
gss_sm |> 
  group_by(bigregion, religion) |> 
  tally() |> 
  mutate(pct = round((n/sum(n))*100, 1)) |> 
  drop_na() |> 
  ggplot(mapping = 
           aes(x = pct, 
               y = reorder(religion, -pct), 
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") + 
    facet_wrap(~ bigregion, ncol = 2)

With this command:

`r chunk_reveal("flipbookexample", platform = "quarto", title = "Flipbookr Runthrough")`

Flipbookr Runthrough

gss_sm
# A tibble: 2,867 × 32
    year    id ballot       age childs sibs   degree race  sex   region income16
   <dbl> <dbl> <labelled> <dbl>  <dbl> <labe> <fct>  <fct> <fct> <fct>  <fct>   
 1  2016     1 1             47      3 2      Bache… White Male  New E… $170000…
 2  2016     2 2             61      0 3      High … White Male  New E… $50000 …
 3  2016     3 3             72      2 3      Bache… White Male  New E… $75000 …
 4  2016     4 1             43      4 3      High … White Fema… New E… $170000…
 5  2016     5 3             55      2 2      Gradu… White Fema… New E… $170000…
 6  2016     6 2             53      2 2      Junio… White Fema… New E… $60000 …
 7  2016     7 1             50      2 2      High … White Male  New E… $170000…
 8  2016     8 3             23      3 6      High … Other Fema… Middl… $30000 …
 9  2016     9 1             45      3 5      High … Black Male  Middl… $60000 …
10  2016    10 3             71      4 1      Junio… White Male  Middl… $60000 …
# ℹ 2,857 more rows
# ℹ 21 more variables: relig <fct>, marital <fct>, padeg <fct>, madeg <fct>,
#   partyid <fct>, polviews <fct>, happy <fct>, partners <fct>, grass <fct>,
#   zodiac <fct>, pres12 <labelled>, wtssall <dbl>, income_rc <fct>,
#   agegrp <fct>, ageq <fct>, siblings <fct>, kids <fct>, religion <fct>,
#   bigregion <fct>, partners_rc <fct>, obama <dbl>

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion)
# A tibble: 2,867 × 32
# Groups:   bigregion, religion [24]
    year    id ballot       age childs sibs   degree race  sex   region income16
   <dbl> <dbl> <labelled> <dbl>  <dbl> <labe> <fct>  <fct> <fct> <fct>  <fct>   
 1  2016     1 1             47      3 2      Bache… White Male  New E… $170000…
 2  2016     2 2             61      0 3      High … White Male  New E… $50000 …
 3  2016     3 3             72      2 3      Bache… White Male  New E… $75000 …
 4  2016     4 1             43      4 3      High … White Fema… New E… $170000…
 5  2016     5 3             55      2 2      Gradu… White Fema… New E… $170000…
 6  2016     6 2             53      2 2      Junio… White Fema… New E… $60000 …
 7  2016     7 1             50      2 2      High … White Male  New E… $170000…
 8  2016     8 3             23      3 6      High … Other Fema… Middl… $30000 …
 9  2016     9 1             45      3 5      High … Black Male  Middl… $60000 …
10  2016    10 3             71      4 1      Junio… White Male  Middl… $60000 …
# ℹ 2,857 more rows
# ℹ 21 more variables: relig <fct>, marital <fct>, padeg <fct>, madeg <fct>,
#   partyid <fct>, polviews <fct>, happy <fct>, partners <fct>, grass <fct>,
#   zodiac <fct>, pres12 <labelled>, wtssall <dbl>, income_rc <fct>,
#   agegrp <fct>, ageq <fct>, siblings <fct>, kids <fct>, religion <fct>,
#   bigregion <fct>, partners_rc <fct>, obama <dbl>

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally()
# A tibble: 24 × 3
# Groups:   bigregion [4]
   bigregion religion       n
   <fct>     <fct>      <int>
 1 Northeast Protestant   158
 2 Northeast Catholic     162
 3 Northeast Jewish        27
 4 Northeast None         112
 5 Northeast Other         28
 6 Northeast <NA>           1
 7 Midwest   Protestant   325
 8 Midwest   Catholic     172
 9 Midwest   Jewish         3
10 Midwest   None         157
# ℹ 14 more rows

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1))
# A tibble: 24 × 4
# Groups:   bigregion [4]
   bigregion religion       n   pct
   <fct>     <fct>      <int> <dbl>
 1 Northeast Protestant   158  32.4
 2 Northeast Catholic     162  33.2
 3 Northeast Jewish        27   5.5
 4 Northeast None         112  23  
 5 Northeast Other         28   5.7
 6 Northeast <NA>           1   0.2
 7 Midwest   Protestant   325  46.8
 8 Midwest   Catholic     172  24.7
 9 Midwest   Jewish         3   0.4
10 Midwest   None         157  22.6
# ℹ 14 more rows

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na()
# A tibble: 20 × 4
# Groups:   bigregion [4]
   bigregion religion       n   pct
   <fct>     <fct>      <int> <dbl>
 1 Northeast Protestant   158  32.4
 2 Northeast Catholic     162  33.2
 3 Northeast Jewish        27   5.5
 4 Northeast None         112  23  
 5 Northeast Other         28   5.7
 6 Midwest   Protestant   325  46.8
 7 Midwest   Catholic     172  24.7
 8 Midwest   Jewish         3   0.4
 9 Midwest   None         157  22.6
10 Midwest   Other         33   4.7
11 South     Protestant   650  61.8
12 South     Catholic     160  15.2
13 South     Jewish        11   1  
14 South     None         170  16.2
15 South     Other         50   4.8
16 West      Protestant   238  37.7
17 West      Catholic     155  24.5
18 West      Jewish        10   1.6
19 West      None         180  28.5
20 West      Other         48   7.6

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion))

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col()

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL)

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none")

Flipbookr Runthrough

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") +
    facet_wrap(~ bigregion, ncol = 2)

Back to Quarto

gss_sm |> 
  group_by(bigregion, religion) |> 
  tally() |> 
  mutate(pct = round((n/sum(n))*100, 1)) |> 
  drop_na() |> 
  ggplot(mapping = 
           aes(x = pct, 
               y = reorder(religion, -pct), 
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") + 
    facet_wrap(~ bigregion, ncol = 2)

Flipbookr Break

Using #BREAK

Flipbookr Break

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na()
# A tibble: 20 × 4
# Groups:   bigregion [4]
   bigregion religion       n   pct
   <fct>     <fct>      <int> <dbl>
 1 Northeast Protestant   158  32.4
 2 Northeast Catholic     162  33.2
 3 Northeast Jewish        27   5.5
 4 Northeast None         112  23  
 5 Northeast Other         28   5.7
 6 Midwest   Protestant   325  46.8
 7 Midwest   Catholic     172  24.7
 8 Midwest   Jewish         3   0.4
 9 Midwest   None         157  22.6
10 Midwest   Other         33   4.7
11 South     Protestant   650  61.8
12 South     Catholic     160  15.2
13 South     Jewish        11   1  
14 South     None         170  16.2
15 South     Other         50   4.8
16 West      Protestant   238  37.7
17 West      Catholic     155  24.5
18 West      Jewish        10   1.6
19 West      None         180  28.5
20 West      Other         48   7.6

Flipbookr Break

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") +
    facet_wrap(~ bigregion, ncol = 2)

Flipbookr Rotate

Using #ROTATE

Flipbookr Rotate

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
  scale_fill_viridis_d(option = "magma") +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") +
    facet_wrap(~ bigregion, ncol = 2)

Flipbookr Rotate

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
  scale_fill_viridis_d(option = "cividis") +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") +
    facet_wrap(~ bigregion, ncol = 2)

Flipbookr Rotate

gss_sm |>
  group_by(bigregion, religion) |>
  tally() |>
  mutate(pct = round((n/sum(n))*100, 1)) |>
  drop_na() |>
  ggplot(mapping =
           aes(x = pct,
               y = reorder(religion, -pct),
               fill = religion)) +
  geom_col() +
  scale_fill_viridis_d(option = "plasma") +
    labs(x = "Percent", y = NULL) +
    guides(fill = "none") +
    facet_wrap(~ bigregion, ncol = 2)

Flipbookr multi

Using break_type to show multiple realizations

(Line highlighting not quite working here)

Flipbookr multi

 cars |>
   sample_frac(size = 1, replace = TRUE) |>
   ggplot() +
   aes(x = speed) +
   aes(y = dist) +
   geom_count(
     alpha = .7,
     color = "blue",
     size = 4
     ) +
   geom_smooth(method = lm, se = FALSE) +
   coord_cartesian(xlim = range(cars$speed),
                   ylim = range(cars$dist)) +
   theme(legend.position = c(.9, .2))

Flipbookr multi

 cars |>
   sample_frac(size = 1, replace = TRUE) |>
   ggplot() +
   aes(x = speed) +
   aes(y = dist) +
   geom_count(
     alpha = .7,
     color = "blue",
     size = 4
     ) +
   geom_smooth(method = lm, se = FALSE) +
   coord_cartesian(xlim = range(cars$speed),
                   ylim = range(cars$dist)) +
   theme(legend.position = c(.9, .2))

Flipbookr multi

 cars |>
   sample_frac(size = 1, replace = TRUE) |>
   ggplot() +
   aes(x = speed) +
   aes(y = dist) +
   geom_count(
     alpha = .7,
     color = "blue",
     size = 4
     ) +
   geom_smooth(method = lm, se = FALSE) +
   coord_cartesian(xlim = range(cars$speed),
                   ylim = range(cars$dist)) +
   theme(legend.position = c(.9, .2))

Flipbookr multi

 cars |>
   sample_frac(size = 1, replace = TRUE) |>
   ggplot() +
   aes(x = speed) +
   aes(y = dist) +
   geom_count(
     alpha = .7,
     color = "blue",
     size = 4
     ) +
   geom_smooth(method = lm, se = FALSE) +
   coord_cartesian(xlim = range(cars$speed),
                   ylim = range(cars$dist)) +
   theme(legend.position = c(.9, .2))

Flipbookr multi

 cars |>
   sample_frac(size = 1, replace = TRUE) |>
   ggplot() +
   aes(x = speed) +
   aes(y = dist) +
   geom_count(
     alpha = .7,
     color = "blue",
     size = 4
     ) +
   geom_smooth(method = lm, se = FALSE) +
   coord_cartesian(xlim = range(cars$speed),
                   ylim = range(cars$dist)) +
   theme(legend.position = c(.9, .2))

Summary