Search code examples
rggplot2texturesgradientgganimate

Add gradients and hand-drawn effects to gganimate plot


I am interested in using gganimate with gradients and hand-drawn and painty-type fill effects (see sketchy and painty and gradients here: https://semiotic.nteract.io/guides/sketchy-painty-patterns). Is this possible? I have found that ggrough (https://xvrdm.github.io/ggrough/) is able to convert ggplot2 objects to have these kinds of effects. However, is it possible to use ggrough or some other thing to combine with gganimate?

And is there another way to do this, even in base ggplot2 (i.e., not using gganimate?) Note that I fear the answer to both questions are no, particularly with gradient fills (see @hadley Hadley Wickhams's answer to this question: How to add texture to fill colors in ggplot2).

Or is there another solution that still uses ggplot2, but not gganimate? I suppose that if it were possible in base ggplot2 that I could make many individual files and stitch them together to make a .gif. Although in theory I could do this using the output from ggrough.


Solution

  • Another option might be to use the xkcd library to get squiggly lines. It doesn't do squiggly fills, but it's a start and is in the right aesthetic neighborhood. I couldn't get it to work out of the box with gganimate, but it's possible to prep your data with tweenr (the same package gganimate relies on) and feed that into gganimate::transition_manual to decent effect:

    enter image description here

    Here's how. Given this fake data:

    library(tidyverse); library(gganimate)
    df <- tibble(Group = rep(1:3, times = 3),
                 value = c(1:6, 3:1),
                 period = rep(1:3, each = 3))
    

    We could animate with geom_rect and gganimate::transition_states. geom_col would be easier here, but I want to show similarity to xkcd::xkcdrect later.

    ggplot() +
      geom_rect(data = df,
               aes(xmin = Group - 0.4, xmax = Group + 0.4,
                   ymin = 0, ymax = value), 
               fill = "gray80") +
      transition_states(period)
    

    enter image description here

    I get an error when I drop in the xkcd::xkcdrect equivalent:

    # Doesn't work
    ggplot() +
      xkcd::xkcdrect(aes(xmin = Group - 0.4, xmax = Group + 0.4,
                         ymin = 0, ymax = value), fill = "gray80",
                     df) +
      transition_states(period)
    

    Error in if (nrow(from) == 0 && nrow(to) == 0) { : missing value where TRUE/FALSE needed In addition: Warning messages: 1: In rep("raw", length = nrow(from)) : first element used of 'length.out' argument 2: In rep("raw", length = nrow(to)) : first element used of 'length.out' argument 3: In rep(NA_integer_, length = nrow(to)) :
    first element used of 'length.out' argument

    But we can get to the same place by prepping the tweened data manually, and then feed that into transition_manual:

    df_tween <- tweenr::tween_states(
      list(df[1:3,],
           df[4:6,],
           df[7:9,],
           df[1:3,]), 3, 1, 'cubic-in-out', 100)
    
    
      ggplot() +
      xkcd::xkcdrect(aes(xmin = Group - 0.4, xmax = Group + 0.4,
                         ymin = 0, ymax = value), fill = "gray80",
                     df_tween) +
      transition_manual(.frame)