knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(ggplot2) library(ggsvg)
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:
{{}}
geom_point_svg(..., defaults = list(...))
scale_svg_*()
to inform ggplot2 how to map values to
this parameter (which it will then insert into the SVG text)#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Generic SVG arrow #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arrow_text <- ' <svg viewBox="0 0 100 100"> <g transform="rotate(45 50 50)"> <line x1="10" y1="50" x2="90" y2="50" stroke="black" stroke-width="2" /> <line x1="70" y1="30" x2="90" y2="50" stroke="black" stroke-width="2" /> <line x1="70" y1="70" x2="90" y2="50" stroke="black" stroke-width="2" /> </g> </svg> ' grid::grid.draw( svg_to_rasterGrob(arrow_text) )
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 )
.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SVG arrow with controllable rotation angle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arrow_text <- ' <svg viewBox="0 0 100 100"> <g transform="rotate({{arrow_angle}} 50 50)"> <line x1="10" y1="50" x2="90" y2="50" stroke="black" stroke-width="2" /> <line x1="70" y1="30" x2="90" y2="50" stroke="black" stroke-width="2" /> <line x1="70" y1="70" x2="90" y2="50" stroke="black" stroke-width="2" /> </g> </svg> ' #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 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 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()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.