class: middle, center # [**thematic**](https://github.com/rstudio/thematic): auto theming for **ggplot2**, **lattice**, and **base** R graphics ### Carson Sievert ### Slides: https://bit.ly/thematic-talk
[@cpsievert](https://twitter.com/cpsievert)
[@cpsievert](https://github.com/cpsievert)
[cpsievert.me](https://cpsievert.me)
<cpsievert1@gmail.com> .footnote[ Slides released under <a href='https://github.com/cpsievert/talks/blob/gh-pages/LICENSE'>Creative Commons</a> ] <style type="text/css"> @import url(https://fonts.googleapis.com/css?family=Pacifico);body{font-family:Roboto Condensed}h1,h2,h3{font-family:Roboto Condensed}.remark-slide-content{background-color:#002B36;color:#FDF6E3}.remark-slide-content a{color:#2AA198}.remark-slide-content.darkly{background-color:#222;color:#FFF}.remark-slide-content.darkly a{color:#0CE3AC}.remark-slide-content.dark-mode{background-color:#444;color:#e4e4e4}.remark-slide-content.dark-mode a{color:#e39777}.remark-slide-content.lucid{background-color:#3D4752;color:#FFFFFF}.remark-slide-content.large{font-size:1.5rem}.remark-slide-content.contrast{background-color:#FFFFFF;color:black} </style> --- ## [**thematic**](https://github.com/rstudio/thematic): auto theming for **ggplot2**, **lattice**, and **base** R graphics Not yet on CRAN, but install it now with: ```r remotes::install_github("rstudio/thematic") library(thematic) ``` For auto-theming in **shiny**, you'll currently need: ```r remotes::install_github("rstudio/shiny#2740") ``` For auto-theming in **rmarkdown**, you'll currently need: ```r remotes::install_github("rstudio/rmarkdown#1706") ``` Learn more <https://rstudio.github.io/thematic/> --- class: middle, center ## RStudio Cloud Demo Visit the demo at <https://bit.ly/thematic-cloud> <div> <a href="https://rstudio.cloud/project/1208127" target="_blank"> <img src="thematic-cloud.svg" alt="RStudio Cloud Example" height="80px" style="display: block; margin: 0 auto;"> </a> </div> --- class: large, contrast, middle ## How can auto-theming fail? How can I fix it? * In some scenarios auto-theming "works", but some additional CSS may be required on plot containers (e.g., **flexdashboard**)...we're working hard to improve such scenarios caused by our own decisions. * In some scenarios auto-theming may "fail" due to lack of information. * Most common scenarios: R terminal and non-HTML output formats in **rmarkdown**. * When auto-theming "fails", it defaults to the usual white background + black foreground. * Auto-theming is entirely optional, avoid it by providing colors (and/or fonts) directly in `thematic_on()` * If you want to "inform" the auto-theming, set defaults via `auto_defaults()`. * Providing values to `thematic_on()` (and/or `auto_defaults()`) is also useful for customizing the theme... --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots The main color settings are `bg`, `fg`, `accent` (they default to `"auto"`). .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span><br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) + <br> geom_point() + <br> geom_smooth()</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-3-1.svg" width="100%" style="display: block; margin: auto;" /> ] (BTW, the values here intentionally match the CSS of my slides) --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Also specify any `font` known to R or any [Google Font](https://fonts.google.com/)<sup>1</sup> (e.g., <span style="font-family:Pacifico">Pacifico</span>) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "<span style='background-color:#ffff7f'>Pacifico</span>"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) + <br> geom_point() + <br> geom_smooth()</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-5-1.svg" width="100%" style="display: block; margin: auto;" /> ] .footnote[ 1. Requires **showtext** or **ragg** to be installed, and potential other "setup" (for details, see <https://rstudio.github.io/thematic>) ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Use `font_spec()` to control other font settings (e.g., `scale`) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font=font_spec("Pacifico", <span style='background-color:#ffff7f'>scale=2</span>)<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) + <br> geom_point() + <br> geom_smooth()</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-7-1.svg" width="100%" style="display: block; margin: auto;" /> ] .footnote[ 1. Requires **showtext** or **ragg** to be installed, and potential other "setup" (for details, see <https://rstudio.github.io/thematic>) ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots **thematic** informs `theme()` _defaults_ (i.e., plot specific code takes priority) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Pacifico"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) + <br> geom_point() + <br> geom_smooth() + <br> theme(axis.title = element_text(color = <span style='background-color:#6C71C4;color:white'>"#6C71C4"</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-9-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots **thematic** informs `theme()` _and geom_ defaults .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#D33682;color:white'>"#D33682"</span>,<br> font = "Pacifico"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) + <br> geom_point(color = <span style='background-color:#586E75;color:white'>"#586E75"</span>) + <br> geom_smooth() + <br> theme(axis.title = element_text(color = <span style='background-color:#6C71C4;color:white'>"#6C71C4"</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-11-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Uses `bg`, `fg`, `accent` to construct a new default for sequential colorscales. .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(<span style='background-color:#ffff7f'>color = cyl</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-13-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Customize with `sequential_gradient()` (here is `fg` -> `accent`) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed",<br> <span style='background-color:#ffff7f'>sequential=sequential_gradient(1,0)</span><br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(<span style='background-color:#ffff7f'>color = cyl</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-15-1.svg" width="100%" style="display: block; margin: auto;" /> ] .footnote[ For more examples, see the [customization article](http://rstudio.github.io/thematic/articles/customize.html). ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Opt-out with `NA`. .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed",<br> <span style='background-color:#ffff7f'>sequential = NA</span><br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(color = cyl))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-17-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Also sets qualitative colorscale defaults to [Okabe-Ito](https://jfly.uni-koeln.de/color/) (colour-blind safe) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(<span style='background-color:#ffff7f'>color=factor(cyl)</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-19-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Customize with any vector of color codes .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed",<br> qualitative = c(<br> <span style='background-color:#1B9E77;color:white'>"#1B9E77"</span>, <span style='background-color:#D95F02;color:white'>"#D95F02"</span>, <span style='background-color:#7570B3;color:white'>"#7570B3"</span><br> )<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(<span style='background-color:#ffff7f'>color=factor(cyl)</span>))</code> For **ggplot2**, `qualitative` is only relevant if there are enough colors to encode the levels. ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-21-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Opt-out with `NA` .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed",<br> <span style='background-color:#ffff7f'>qualitative = NA</span><br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> geom_point(aes(<span style='background-color:#ffff7f'>color=factor(cyl)</span>))</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-23-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots [**thematic**](https://github.com/rstudio/thematic) works with **ggplot2** (and extensions) .pull-left[ <code class ='r hljs remark-code'>thematic_on(<br> bg = <span style='background-color:#002B36;color:white'>"#002B36"</span>, <br> fg = "#FDF6E3", <br> accent = <span style='background-color:#2AA198;color:white'>"#2AA198"</span>,<br> font = "Roboto Condensed"<br>)<br>library(ggplot2)<br>ggplot(mtcars, aes(wt, mpg)) +<br> <span style='background-color:#ffff7f'>ggrepel::geom_text_repel</span>(<br> aes(color = factor(cyl), label = row.names(mtcars))<br> )</code> ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-25-1.svg" width="100%" style="display: block; margin: auto;" /> ] --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Also **lattice** graphics: <code class ='r hljs remark-code'><span style='background-color:#ffff7f'>lattice</span>::show.settings()</code> <img src="index_files/figure-html/unnamed-chunk-27-1.svg" width="80%" style="display: block; margin: auto;" /> --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots Also **base** graphics: ```r par(mfrow = c(1, 2)) hist(rnorm(100)) plot(rep(1:5, each = 5), rep(1:5, 5), col = 1:25, pch = 1:25) ``` <img src="index_files/figure-html/unnamed-chunk-28-1.svg" width="80%" style="display: block; margin: auto;" /> --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots ...but, for accents, you'll have to inform `col` <code class ='r hljs remark-code'>plot(cars, main = "Stopping Distance versus Speed")<br>lines(stats::lowess(cars), <span style='background-color:#ffff7f'>col = thematic_get_option("accent")</span>)</code> <img src="index_files/figure-html/unnamed-chunk-30-1.svg" width="80%" style="display: block; margin: auto;" /> --- ## [**thematic**](https://github.com/rstudio/thematic): simplified theming of R plots ...and same for sequential colorscales <code class ='r hljs remark-code'>par(mfrow = c(1, 2))<br>image(volcano)<br>image(volcano, <span style='background-color:#ffff7f'>col = thematic_get_option("sequential")</span>)</code> <img src="index_files/figure-html/unnamed-chunk-32-1.svg" width="80%" style="display: block; margin: auto;" /> --- class: contrast, middle, center ## What about auto-theming in other plots, tables, etc? Hope is on the way... --- class: contrast ### The real magic: `getCurrentOutputInfo()` Any **shiny** output with a special `.shiny-report-theme` class will ([soon](https://github.com/rstudio/shiny/pull/2740)) report it's computed CSS styles. .pull-left[ ```r library(shiny) shinyApp( fluidPage( theme = shinythemes::shinytheme("superhero"), titlePanel("superhero styles"), tagAppendAttributes( verbatimTextOutput("info"), * class = "shiny-report-theme" ) ), function(input, output) { output$info <- renderPrint({ * str(getCurrentOutputInfo()) }) } ) ``` ] .pull-right[ <img src="superhero-styles.png" width="100%"> ] --- class: contrast ### The real magic: `getCurrentOutputInfo()` **thematic** uses `getCurrentOutputInfo()` for auto-theming in **shiny**, but technically _any R code_ could leverage this info to set sensible theming defaults. .pull-left[ ```r library(shiny) shinyApp( fluidPage( theme = shinythemes::shinytheme("superhero"), titlePanel("superhero styles"), tagAppendAttributes( verbatimTextOutput("info"), * class = "shiny-report-theme" ) ), function(input, output) { output$info <- renderPrint({ * str(getCurrentOutputInfo()) }) } ) ``` ] .pull-right[ <img src="superhero-styles.png" width="100%"> ] --- class: contrast ### The real magic: `getCurrentOutputInfo()` In the near future, things like **plotly**, **DT**, etc will take advantage. (If you're **htmlwidgets** developer, `shinyWidgetOutput()` will [soon](https://github.com/ramnathv/htmlwidgets/pull/361) gain a `reportTheme` argument). .pull-left[ ```r library(shiny) shinyApp( fluidPage( theme = shinythemes::shinytheme("superhero"), titlePanel("superhero styles"), tagAppendAttributes( verbatimTextOutput("info"), * class = "shiny-report-theme" ) ), function(input, output) { output$info <- renderPrint({ * str(getCurrentOutputInfo()) }) } ) ``` ] .pull-right[ <img src="superhero-styles.png" width="100%"> ] --- class: contrast, middle, center # Where can I learn more about modern approaches to styling in shiny and rmarkdown? The new [**bslib** package](https://rstudio.github.io/bslib/index.html) makes it possible to style **shiny** and **rmarkdown** in R (via **sass**) instead of CSS. Check out [this article](https://rstudio.github.io/bslib/articles/recipes.html) for a good sense of where things are (more to come). (BTW, **bslib** is what makes auto-theming in `html_document()` feasible) --- class: large ## Summary * Call `thematic_on()`/`thematic_off()` to enable/disable **thematic**. * By default, `"auto"` colors are enabled...this generally works if: * A **shiny** runtime is generating the plots. * Plots are generated when `rmarkdown::html_document()` is rendered (this won't work with conflicting custom CSS, [but there's a workaround](https://rstudio.github.io/thematic/articles/rmarkdown.html)). * Inside RStudio. * Use `thematic_on(font = "auto")` to enable auto fonts...this generally works if it resolves to a Google Font (or font known to R). * For Google Fonts, you'll also need **ragg** or **showtext** installed and some other setup (see the respective [Shiny](https://rstudio.github.io/thematic/articles/shiny.html), [R Markdown](https://rstudio.github.io/thematic/articles/rmarkdown.html), and [RStudio](https://rstudio.github.io/thematic/articles/rstudio.html) articles) * Provide values directly to `thematic_on()` and/or `auto_defaults()` to customize. --- class: center, middle ## Thank you! Any questions? ### Slides: <https://bit.ly/thematic-talk> ### Learn more: <https://rstudio.github.io/thematic> #### Contact
<a href='https://twitter.com/cpsievert'>@cpsievert</a> <br />
<a href='https://github.com/cpsievert'>@cpsievert</a> <br />
<cpsievert1@gmail.com> <br />
<https://cpsievert.me/> .footnote[ Slides made possible thanks to [**xaringan**](https://github.com/yihui/xaringan) and [**flair**](https://github.com/kbodwin/flair) ]