--- title: "Non-Standard Aesthetic: Rotation" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Non-Standard Aesthetic: Rotation} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(ggplot2) library(ggsvg) ``` ## Introduction This example steps through the process of creating an SVG and mapping an SVG characteristic into a ggplot2 aesthetic. ggplot2 aesthethics are not limited to colour, fill, size etc. *Anything* in SVG can be used as a target for an aesthetic mapping. In this example the **rotation** of an SVG arrow is controlled via a value in a data.frame. Overview: 1. Introduce parameters with [glue](https://cran.r-project.org/package=glue) syntax, using double curly braces `{{}}` 2. Set the defaults for these parameters using `geom_point_svg(..., defaults = list(...))` 3. Use these parameters as aesthetics 4. Add an appropriate `scale_svg_*()` to inform ggplot2 how to map values to this parameter (which it will then insert into the SVG text) #### Define the base SVG ```{r fig.height=1.5} #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Generic SVG arrow #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arrow_text <- ' ' grid::grid.draw( svg_to_rasterGrob(arrow_text) ) ``` #### Create parameterised SVG In order to create a responsive SVG that has values dynamically mapped in `ggplot2`, add named parameters in place of values in the SVG text. In this example the SVG transform to rotate the arrow is `rotate(45 50 50)` and this has been parameterised to `rotate({{angle}} 50 50 )`. ```{r fig.height=1.5} #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SVG arrow with controllable rotation angle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arrow_text <- ' ' #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Test the rotation is changed as 'angle' is changed #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arrow_angle <- -30 final_svg <- glue::glue(arrow_text, .open = "{{", .close = "}}") grid::grid.draw( svg_to_rasterGrob(final_svg) ) ``` #### Create a plot with rotating SVG arrow ```{r fig.width = 6, fig.height=4} #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a plausible vector field #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ set.seed(13) value <- 360 * as.vector(ambient::normalise(ambient::noise_perlin(c(10, 10)))) data <- cbind(expand.grid(x=1:10, y=1:10), value) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Use 'value' to control the arrow angle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ggplot(data) + geom_raster(aes(x, y, fill = value)) + geom_point_svg( aes(x, y, arrow_angle = I(value)), svg = arrow_text, size = 10#, # defaults = list(arrow_angle = 0) ) + theme_bw() + theme(legend.position = 'none') + scale_fill_viridis_c() ```