diff --git a/rphylopic/img/rphylopic-radial-phylogeny.png b/rphylopic/img/rphylopic-radial-phylogeny.png new file mode 100644 index 0000000..de86617 Binary files /dev/null and b/rphylopic/img/rphylopic-radial-phylogeny.png differ diff --git a/rphylopic/index.qmd b/rphylopic/index.qmd new file mode 100644 index 0000000..61c79c2 --- /dev/null +++ b/rphylopic/index.qmd @@ -0,0 +1,184 @@ +--- +title: "Introduction to rphylopic" +description: "An R package that allows users to easily fetch and visualize silhouettes of organisms from PhyloPic." +author: + - William Gearty + - Lewis A. Jones +date: "`r Sys.Date()`" +categories: [r, ggplot2, dataviz] +difficulty: Beginner +image: img/rphylopic-radial-phylogeny.png +format: + html: + toc: true + revealjs: + smaller: true + output-file: index-slides.html + css: style/template.css + slide-number: c/t + include-in-header: style/header.html + include-after-body: style/footer.html +execute: + output-location: fragment + echo: true + warning: false + message: false + freeze: auto +filters: + - at: pre-ast + path: web_and_slides_autogenerated.lua +editor: + markdown: + wrap: 72 +--- + + + + +## Introduction + +### What is PhyloPic + +[PhyloPic](https://www.phylopic.org) is an open database of free silhouette images of animals, plants, and other life forms, available for reuse under Creative Commons licenses. At time of writing, >13,000 silhouette images are available covering a broad array of biological groups from dinosaurs and corals to grasses and viruses. To date, the silhouettes have been created by over 500 volunteer contributors, and are increasingly used in data visualisation. + +### What is **rphylopic** + +::: {.narration} + +**rphylopic** is a package that allows users to easily fetch and visualize silhouettes of organisms from [PhyloPic](https://www.phylopic.org/). The package allows users to add silhouettes as layers or as data points to both base R and ggplot2 plots. Additional functionality allows users to pick between available silhouettes, transform them (e.g., rotate and recolor), and save image files. This module will give you an overview of the package and provide example usage. + +::: + +::: {.slides-only} + +- a bullet summary for the slide +- which would be redundant on the page + +::: + +### Installation + +## Using rphylopic + +### Getting silhouettes + +::: {.narration} +Every silhouette available via PhyloPic has a universally unique identifier (UUID). The first step to get a PhyloPic silhouette into R is to 1) identify the silhouette you want and then 2) identify the UUID for that silhouette. rphylopic provides a couple different ways to do this: +::: + +::: {.narration} +The simplest way to do this is to use the `get_uuid()` function. You can use this function to search PhyloPic based on a taxonomic or phylogenetic name (e.g., Canis lupus or pan-Mollusca). However, multiple silhouettes (and hence UUIDs) can exist for a searched name. The n argument in `get_uuid()` allows you to fetch n matched UUIDs. Using a returned UUID, you can then fetch the respective silhouette using `get_phylopic()`. +::: + +```{r} +# Load rphylopic +library(rphylopic) +# Get a single image UUID for a species +uuid <- get_uuid(name = "Canis lupus") +# Get the image for that UUID +img <- get_phylopic(uuid = uuid) +plot(img) +``` + +```{r} +# But multiple silhouettes can exist per species... +uuid <- get_uuid(name = "Canis lupus", n = 5) +``` + +## One plot per slide + +::: {.narration} +Each `##` heading starts a slide, and the filter closes the slide after every +figure, so two plots never share one slide. Prose after a figure introduces the next +figure rather than trailing behind the old one. +::: + +::: {.panel-tabset} + +### Tab A + +```{r} +#| code-fold: true +plot(mtcars$wt, mtcars$mpg) +``` + +### Tab B + +```{r} +plot(mtcars$hp, mtcars$mpg) +``` + +::: + +```{r} +plot(mtcars$wt, mtcars$mpg) +``` + +::: {.narration} +This narration belongs to the plot below, and lands on its slide as speaker notes. +::: + +```{r} +plot(mtcars$hp, mtcars$mpg) +``` + +## Deeper headings + +::: {.narration} +`###` and deeper headings are promoted to slide level, so each becomes its own +slide instead of piling onto the previous slide. On the website they stay a normal +sub-heading. +::: + +### A sub-heading + +::: {.narration} +This is its own slide. +::: + +## Building up a slide + +::: {.narration} +When a slide holds two or more code chunks, the filter expands it into an +auto-animate build-up: one step per chunk, earlier chunks staying on screen, and +the narration advancing with each step/click. +::: + +```{r} +x <- mtcars$wt +mean(x) +``` + +::: {.narration} +The second chunk arrives on the next step, with the first still visible. +::: + +```{r} +round(sd(x), 3) +``` + +## Callouts + +::: {.narration} +A callout gets a slide of its own. The content is un-boxed and the slide is titled by its own heading. +::: + +::: {.callout-note} +## A note + +This box is dropped on the slide, which lets a figure inside it stretch to fit. +::: + +::: {.callout-caution collapse="true"} +## An exercise solution + +A *collapsed* callout is the exception: it keeps its box. Since clicking on +slides can be awkward, the collapsed content is held back as a fragment and +revealed when you advance. On the website it stays a click-to-open box. +::: + +## More info + +- [Quarto revealjs](https://quarto.org/docs/presentations/revealjs/) +- [Callouts](https://quarto.org/docs/authoring/callouts.html) +- the repo README, for the other two ways to build a module diff --git a/rphylopic/style/logo_top_right.png b/rphylopic/style/logo_top_right.png new file mode 100644 index 0000000..72455f2 Binary files /dev/null and b/rphylopic/style/logo_top_right.png differ diff --git a/rphylopic/style/template.css b/rphylopic/style/template.css new file mode 100644 index 0000000..7a61ee0 --- /dev/null +++ b/rphylopic/style/template.css @@ -0,0 +1,125 @@ +/* Same background as on the website */ +.reveal .slide-background { + background: rgb(245.4, 250.35, 250.65); +} + +p, +h1, +h2, +h3, +h4, +h5, +h6, +ul, +ol, +li, +center, +.quarto-title-authors { + color: #575756 !important; +} + +/* Logo pinned in the top right corner of every slide */ +.reveal::after { + content: ""; + position: fixed; + right: 10%; + top: -5px; + width: 15%; + height: 15%; + background-image: url(logo_top_right.png); + background-size: contain; + background-position: right bottom; + background-repeat: no-repeat; + z-index: 10; +} + +/* Social links footer, on the title slide only */ +.title-footer { + display: none; + position: fixed; + bottom: 0; + left: 0; + height: 3%; + width: 100%; + padding: 0.6em 1em; + text-align: center; + font-family: var(--r-main-font); + font-size: 18px; + color: white; + background-color: #0d725a; + z-index: 10; +} + +.title-footer span { + margin: 0 1.5em; +} + +.title-footer a { + display: inline-flex; + align-items: center; + color: white; + text-decoration: none; +} + +.title-footer i { + font-size: 1.4em; +} + +body:has(#title-slide.present) .title-footer { + display: flex; + align-items: center; + justify-content: center; +} + +/* Larger logo on the title slide */ +.reveal:has(#title-slide.present)::after { + width: 30%; + height: 30%; + left: 33%; + top: -45px; +} + +/* Recolor the menu icon (it is an image, not a glyph) */ +body:has(#title-slide.present) .reveal .slide-menu-button .fa-bars::before { + filter: brightness(0) invert(1); +} + +h1 { + text-align: center; +} + +/* Slide numbers: plain text, not on the title slide */ +.reveal .slide-number a { + color: #575756; + text-decoration: none; + pointer-events: none; +} + +body:has(#title-slide.present) .reveal .slide-number { + display: none !important; +} + +/* Code almost at the same size as the surrounding text */ +.reveal code { + font-size: 0.9em; +} + +.reveal pre { + font-size: 0.7em; +} + +/* Slightly rounded code blocks */ +.reveal div.sourceCode { + border-radius: 8px; + overflow: hidden; + border: 1px solid #0d725a; +} + +.reveal pre { + border-radius: 8px; +} + +/* Wrap the slide title to avoid overlapping with the logo in the top right corner */ +section>h2 { + width: 85%; +} \ No newline at end of file diff --git a/rphylopic/web_and_slides_autogenerated.lua b/rphylopic/web_and_slides_autogenerated.lua new file mode 100644 index 0000000..dd7ad54 --- /dev/null +++ b/rphylopic/web_and_slides_autogenerated.lua @@ -0,0 +1,307 @@ +-- web_and_slides_autogenerated.lua -- AUTOGENERATED, DO NOT EDIT. +-- Copied from the repo root's web_and_slides.lua by sync_filter.r (see _quarto.yml). +-- Edit that file instead; this copy exists so the module is self-contained. +-- +-- web_and_slides.lua +-- Combined filter for dual html + revealjs Quarto modules: +-- * Div : `::: {.narration}` -> speaker notes on revealjs, plain prose elsewhere. +-- `::: {.slides-only}` -> revealjs slides only: dropped elsewhere +-- (equivalent to `::: {.content-visible when-format="revealjs"}`) +-- `::: {.html-only}` -> html only: dropped on revealjs slides +-- (equivalent to `::: {.content-hidden when-format="revealjs"}`) +-- * Pandoc : on revealjs, headings below the slide level are promoted so each +-- becomes its own slide, the slide closes after each plot (so no two +-- plots share a slide and a plot's following prose stays with the +-- next plot -- unless only prose remains before the next heading, in +-- which case it stays put rather than making a blank slide), and each +-- callout is unwrapped onto its own slide titled by its own heading +-- (no box, so any figure inside hoists and stretches; an untitled +-- callout keeps the section title; a callout the author collapsed +-- keeps its box, its body held back as a fragment, since revealjs +-- ignores Quarto's `collapse`). Split slides repeat the current +-- heading so they keep a title. Finally, any slide with 2+ cells is +-- expanded into an auto-animate build-up (one step per cell, cells +-- accumulating, notes advancing) so each step is a real slide whose +-- figure still hoists and auto-stretches; an interactive quarto-live +-- cell is skipped there, since duplicating it duplicates the editor. +-- Other formats untouched. +-- Register at the `pre-ast` stage so callouts are still plain divs here (Quarto +-- normalizes them into custom AST nodes after that point). + +function Div(el) + if el.classes:includes("slides-only") then + if not quarto.doc.is_format("revealjs") then + return {} -- slides only: nothing on the website + end + return el.content + end + if el.classes:includes("html-only") then + if quarto.doc.is_format("revealjs") then + return {} -- html only: nothing on the slides + end + return el.content + end + if not el.classes:includes("narration") then + return nil -- leave every other div alone + end + if quarto.doc.is_format("revealjs") then + el.classes = el.classes:filter(function(c) return c ~= "narration" end) + el.classes:insert("notes") -- Pandoc emits