Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a stacked histogram with gganimate

I'm trying to show a histogram building over time. It would start with, say, 1952 data, then each year update the histogram, growing.

The path seems to be gganimate, and I would think using transition_reveal to slowly reveal more data over time. This does not appear to work.

Let's say I start with this:

library(gapminder)
library(tidyverse)
library(gganimate)

ggplot(gapminder, 
       aes(lifeExp, fill = fct_rev(factor(year)), group = fct_rev(factor(year)))) +
  geom_histogram(position = "stack", bins = 20) +
  transition_reveal(year)  

which fails badly.

I can sort of kludge things together with transition_layer, like so:

ggplot(gapminder, aes(lifeExp, fill = fct_rev(factor(year)))) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1952)) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1957)) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1962)) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1967)) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1972)) +
  geom_histogram(position = "stack", bins = 20, 
                 data = filter(gapminder, year<= 1977)) +
  transition_layers()  

which produces the desired result, but is unwieldy. Is there a more portable way?

Here is a gif of what I'm looking for:

Growing stacked histogram

like image 339
Frank Avatar asked Apr 26 '19 05:04

Frank


1 Answers

I couldn't figure it out using geom_histogram, but I could by making a stacked histogram from geom_rect.

bin_yrs = 2
a <- gapminder %>%
  count(year, life_bin = floor(lifeExp / bin_yrs) * bin_yrs) %>%
  complete(year, life_bin, fill = list(n = 0)) %>%
  arrange(year, life_bin) %>%
  group_by(life_bin) %>%
  mutate(dummy = lag(cumsum(n), default = 0)) %>%
  ungroup() %>%

  ggplot(aes(xmin = life_bin, 
             xmax = life_bin + bin_yrs,
             ymin = dummy, 
             ymax = dummy + n,
             fill = as.factor(year))) +
  geom_rect() +
  transition_manual(year) +
  shadow_trail()
animate(a, nframes = 12, fps = 4, width = 600, height = 300)

enter image description here

like image 162
Jon Spring Avatar answered Sep 21 '22 16:09

Jon Spring