custom-aesthetics-glue-strings

library(ggsvg)
library(ggplot2)

Introduction

Using custom glue strings within SVG allow for customised control of SVG rendering.

Rendering is not limited to CSS Selector properties. You can insert text dynamically for parameters such as animation parameters, class names or really anything within an SVG.

Test data

test_df <- data.frame(
  x = runif(10), 
  y = runif(10), 
  count = sample(3:5, 10, T),
  type  = sample(c('a', 'b', 'c'), 10, T))

test_df
#>             x          y count type
#> 1  0.65768742 0.24786692     4    c
#> 2  0.44489091 0.18043804     4    c
#> 3  0.66011963 0.06566287     5    b
#> 4  0.92905594 0.72166486     5    a
#> 5  0.79785976 0.67869091     4    c
#> 6  0.18430019 0.31986834     3    b
#> 7  0.88861117 0.69646570     5    b
#> 8  0.85751850 0.49458148     3    c
#> 9  0.60190520 0.71678003     4    a
#> 10 0.09403182 0.39740571     4    b

Mapping Aesthetics with {glue} strings

Here is a simple SVG consisting of 2 stacked circles - a big circle on the bottom and a small circle resting on top.

snowman_txt <- '
  <svg viewBox="0 0 100 100 ">
    <circle id="top" cx="50" cy="20" r="20" fill="brown" stroke="black" />
    <circle id="bot" cx="50" cy="70" r="30" fill="brown" stroke="black" />
  </svg>
  '

grid::grid.draw( svg_to_rasterGrob(snowman_txt, width=800, height=800) )

In this example, I want to be able to map values to the fill colour for the top and bottom circles.

To do this I insert formatting strings as used in the glue package i.e. insert new mapped variables {{bot_fill}} and {{top_fill}}.

When creating the plot, ggsvg will fill in these locations with appropriately mapped variables dependend on what scale_svg*() are applied to tplot

snowman_txt <- '
  <svg viewBox="0 0 100 100 ">
    <circle id="top"  cx="50" cy="20" r="20" fill="{{top_fill}}" stroke="black" />
    <circle id="bot"  cx="50" cy="70" r="30" fill="{{bot_fill}}" stroke="black" />
  </svg>
  '

ggplot(test_df) + 
  geom_point_svg(aes(x, y, top_fill = count), 
                 svg = snowman_txt, size = 20,
                 bot_fill='#aaaaaa') + 
  theme_bw() + 
  scale_svg_default() 
#> Warning: The `scale_name` argument of `continuous_scale()` is deprecated as of ggplot2
#> 3.5.0.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.

ggplot(test_df) + 
  geom_point_svg(aes(x, y, top_fill = count), 
                 svg = snowman_txt, size = 20,
                 bot_fill='#aaaaaa') + 
  theme_bw() + 
  scale_svg_fill_viridis_c(aesthetics = "top_fill")

ggplot(test_df) + 
  geom_point_svg(aes(x, y, 
                     top_fill = count, bot_fill = x), 
                 svg = snowman_txt, size = 20) + 
  theme_bw() + 
  scale_svg_fill_viridis_c(aesthetics = "top_fill") +
  scale_svg_fill_viridis_c(aesthetics = "bot_fill", option = 'A')

Preferred naming for custom aesthetics

Custom aesthetics should be named with a _[type] suffix in order to keep {ggsvg} working well with {ggplot2}. E.g:

  • Use shade_fill. Not shade or fill_shade
  • Use rect_size. Not size_rect or rect_bigness
  • Use path_alpha. Not transparency

The type suffix should be any of the standard ggplot aesthetics (fill, colour, size etc).

The prefix can be any name that makes sense to you.

Naming in this way will allow multiple fill aesthetics as long as they have a unique name.