├── .gitignore ├── LICENSE ├── README.md ├── libs └── remark-css │ ├── default-fonts.css │ └── default.css ├── many-model-performance.gif ├── render-gif.R ├── tidyverse-gifs.Rproj ├── xarigan-slides-example.html ├── xarigan-slides-example.pdf ├── xarigan-slides-example_files └── figure-html │ └── plot-results-1.png ├── xaringan-slides-example.Rmd ├── xaringan-slides-example.html ├── xaringan-slides-example.pdf └── xaringan-slides-example_files └── figure-html └── plot-results-1.png /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # User-specific files 9 | .Ruserdata 10 | 11 | # Example code in package build process 12 | *-Ex.R 13 | 14 | # Output files from R CMD build 15 | /*.tar.gz 16 | 17 | # Output files from R CMD check 18 | /*.Rcheck/ 19 | 20 | # RStudio files 21 | .Rproj.user/ 22 | 23 | # produced vignettes 24 | vignettes/*.html 25 | vignettes/*.pdf 26 | 27 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 28 | .httr-oauth 29 | 30 | # knitr and R markdown default cache directories 31 | *_cache/ 32 | /cache/ 33 | 34 | # Temporary files created by R markdown 35 | *.utf8.md 36 | *.knit.md 37 | 38 | # R Environment Variables 39 | .Renviron 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Bryan Shalloway 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tidyverse-gifs 2 | 3 | Provides an example of how to create a gif using: 4 | 5 | `flair` --> `xaringan` + `pagedown` --> `magick` 6 | 7 | * [flair](https://github.com/kbodwin/flair) for the code highlighting 8 | * [xaringan](https://github.com/yihui/xaringan) for the slides 9 | * [pagedown](https://github.com/rstudio/pagedown) to convert the html slides into pdf 10 | * [magick](https://github.com/ropensci/magick) to convert the pdf into images, crop images, and then stitch them together into a gif 11 | 12 | **Steps:** 13 | 14 | 1. Create slides (e.g. "xaringan-slides-example.Rmd") 15 | 2. Render slides into a gif (e.g. "render-gif.R") 16 | 17 | **Example of resulting output:** 18 | 19 | ![Example gif](many-model-performance.gif) 20 | 21 | **Improved method:** 22 | 23 | I posted an easier approach (largely superseding this one) that uses: 24 | 25 | `flipbookr` --> `pagedown` --> `magick` to create types of gifs in a way that does not require nearly as much copying and pasting of code [brshallo/flipbookr-gifs-examples](https://github.com/brshallo/flipbookr-gifs-examples). 26 | 27 | -------------------------------------------------------------------------------- /libs/remark-css/default-fonts.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz); 2 | @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic); 3 | @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700); 4 | 5 | body { font-family: 'Droid Serif', 'Palatino Linotype', 'Book Antiqua', Palatino, 'Microsoft YaHei', 'Songti SC', serif; } 6 | h1, h2, h3 { 7 | font-family: 'Yanone Kaffeesatz'; 8 | font-weight: normal; 9 | } 10 | .remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; } 11 | -------------------------------------------------------------------------------- /libs/remark-css/default.css: -------------------------------------------------------------------------------- 1 | a, a > code { 2 | color: rgb(249, 38, 114); 3 | text-decoration: none; 4 | } 5 | .footnote { 6 | position: absolute; 7 | bottom: 3em; 8 | padding-right: 4em; 9 | font-size: 90%; 10 | } 11 | .remark-code-line-highlighted { background-color: #ffff88; } 12 | 13 | .inverse { 14 | background-color: #272822; 15 | color: #d6d6d6; 16 | text-shadow: 0 0 20px #333; 17 | } 18 | .inverse h1, .inverse h2, .inverse h3 { 19 | color: #f3f3f3; 20 | } 21 | /* Two-column layout */ 22 | .left-column { 23 | color: #777; 24 | width: 20%; 25 | height: 92%; 26 | float: left; 27 | } 28 | .left-column h2:last-of-type, .left-column h3:last-child { 29 | color: #000; 30 | } 31 | .right-column { 32 | width: 75%; 33 | float: right; 34 | padding-top: 1em; 35 | } 36 | .pull-left { 37 | float: left; 38 | width: 47%; 39 | } 40 | .pull-right { 41 | float: right; 42 | width: 47%; 43 | } 44 | .pull-right ~ * { 45 | clear: both; 46 | } 47 | img, video, iframe { 48 | max-width: 100%; 49 | } 50 | blockquote { 51 | border-left: solid 5px lightgray; 52 | padding-left: 1em; 53 | } 54 | .remark-slide table { 55 | margin: auto; 56 | border-top: 1px solid #666; 57 | border-bottom: 1px solid #666; 58 | } 59 | .remark-slide table thead th { border-bottom: 1px solid #ddd; } 60 | th, td { padding: 5px; } 61 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } 62 | 63 | @page { margin: 0; } 64 | @media print { 65 | .remark-slide-scaler { 66 | width: 100% !important; 67 | height: 100% !important; 68 | transform: scale(1) !important; 69 | top: 0 !important; 70 | left: 0 !important; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /many-model-performance.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brshallo/tidyverse-gifs/ad5d7e739e28af80d2053d21b529fe754d388dc9/many-model-performance.gif -------------------------------------------------------------------------------- /render-gif.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | library(magick) 3 | 4 | # create pdf of slides 5 | pagedown::chrome_print("xaringan-slides-example.Rmd") 6 | 7 | # load slides as images 8 | images <- image_read_pdf("xaringan-slides-example.pdf", density = 100) 9 | 10 | # crop, transform images, render to gif 11 | images %>% 12 | image_crop("0x350") %>% 13 | image_write_gif(here::here("many-model-performance.gif"), 14 | delay = 1.5) 15 | -------------------------------------------------------------------------------- /tidyverse-gifs.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /xarigan-slides-example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | xarigan-slides-example.utf8.md 5 | 6 | 7 | 8 | 9 | 10 | 152 | 153 | 154 | 241 | 242 | 261 | 262 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /xarigan-slides-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brshallo/tidyverse-gifs/ad5d7e739e28af80d2053d21b529fe754d388dc9/xarigan-slides-example.pdf -------------------------------------------------------------------------------- /xarigan-slides-example_files/figure-html/plot-results-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brshallo/tidyverse-gifs/ad5d7e739e28af80d2053d21b529fe754d388dc9/xarigan-slides-example_files/figure-html/plot-results-1.png -------------------------------------------------------------------------------- /xaringan-slides-example.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | xaringan::moon_reader: 4 | lib_dir: libs 5 | nature: 6 | highlightStyle: github 7 | highlightLines: true 8 | countIncrementalSlides: false 9 | --- 10 | 11 | ```{r setup, include=FALSE} 12 | options(htmltools.dir.version = FALSE) 13 | 14 | knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE) 15 | ``` 16 | 17 | ```{css, echo = FALSE} 18 | .remark-slide-content { 19 | padding-top: 10px; 20 | padding-left: 10px; 21 | padding-right: 10px; 22 | padding-bottom: 10px; 23 | } 24 | 25 | .remark-code, .remark-inline-code { font-family: 'Source Code Pro', 'Lucida Console', Monaco, monospace; 26 | font-size: 60%; 27 | } 28 | ``` 29 | 30 | ```{r include = FALSE} 31 | library(tidyverse) 32 | library(flair) 33 | library(gapminder) 34 | ``` 35 | 36 | .pull-left[ 37 | ```{r, echo = TRUE, eval = FALSE} 38 | gapminder 39 | ``` 40 | ] 41 | 42 | .pull-right[ 43 | ```{r, echo = FALSE} 44 | gapminder 45 | ``` 46 | ] 47 | 48 | --- 49 | 50 | .pull-left[ 51 | ```{r, echo = FALSE} 52 | flair::decorate_chunk("nest", eval = FALSE) %>% 53 | flair("group_by") %>% 54 | flair("nest") 55 | ``` 56 | ] 57 | 58 | .pull-right[ 59 | ```{r nest, echo = FALSE} 60 | gapminder %>% 61 | group_by(country, continent) %>% 62 | nest() 63 | ``` 64 | ] 65 | 66 | --- 67 | 68 | .pull-left[ 69 | ```{r, echo = FALSE} 70 | flair::decorate_chunk("mutate", eval = FALSE) %>% 71 | flair("mutate") 72 | ``` 73 | ] 74 | 75 | .pull-right[ 76 | ```{r mutate, echo = FALSE} 77 | gapminder %>% 78 | group_by(country, continent) %>% 79 | nest() %>% 80 | mutate(model = map(data, 81 | ~lm(lifeExp ~ year, data = .x)), 82 | results = map(model, broom::glance)) 83 | ``` 84 | ] 85 | 86 | --- 87 | 88 | .pull-left[ 89 | ```{r, echo = FALSE} 90 | flair::decorate_chunk("unnest", eval = FALSE) %>% 91 | flair("unnest") 92 | ``` 93 | ] 94 | 95 | .pull-right[ 96 | ```{r unnest, echo = FALSE} 97 | gapminder %>% 98 | group_by(country, continent) %>% 99 | nest() %>% 100 | mutate(model = map(data, 101 | ~lm(lifeExp ~ year, data = .x)), 102 | results = map(model, broom::glance)) %>% 103 | unnest(results) 104 | ``` 105 | ] 106 | --- 107 | 108 | .pull-left[ 109 | ```{r, echo = FALSE} 110 | flair::decorate_chunk("plot-results", eval = FALSE) %>% 111 | flair("ggplot") %>% 112 | flair("ggbeeswarm::geom_quasirandom") 113 | ``` 114 | ] 115 | 116 | .pull-right[ 117 | ```{r plot-results, echo = FALSE} 118 | gapminder %>% 119 | group_by(country, continent) %>% 120 | nest() %>% 121 | mutate(model = map(data, 122 | ~lm(lifeExp ~ year, data = .x)), 123 | results = map(model, broom::glance)) %>% 124 | unnest(results) %>% 125 | ggplot(aes(x = continent, y = r.squared)) + 126 | ggbeeswarm::geom_quasirandom() 127 | ``` 128 | ] 129 | -------------------------------------------------------------------------------- /xaringan-slides-example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | xaringan-slides-example.utf8.md 5 | 6 | 7 | 8 | 9 | 10 | 152 | 153 | 154 | 241 | 242 | 261 | 262 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /xaringan-slides-example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brshallo/tidyverse-gifs/ad5d7e739e28af80d2053d21b529fe754d388dc9/xaringan-slides-example.pdf -------------------------------------------------------------------------------- /xaringan-slides-example_files/figure-html/plot-results-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brshallo/tidyverse-gifs/ad5d7e739e28af80d2053d21b529fe754d388dc9/xaringan-slides-example_files/figure-html/plot-results-1.png --------------------------------------------------------------------------------