Animated dot histogram, built observation by observation (using gganimate in R)

前端 未结 3 819
庸人自扰
庸人自扰 2021-02-12 14:37

I would like to sample points from a normal distribution, and then build up a dotplot one by one using the gganimate package until the final frame shows the full do

3条回答
  •  南方客
    南方客 (楼主)
    2021-02-12 14:54

    Another option is to draw the points with another geom. you will need to do some counts on your data first (and binning) but it doesn’t require making your data longer.

    For example, you can use geom_point, but the challenge will be to get the dimensions of your points right, so they touch/do not touch. This depends on the device / file size.

    But you can also just use ggforce::geom_ellipse to draw your dots:)

    geom_point (trial and error with device dimensions)

    library(tidyverse)
    library(gganimate)
    
    set.seed(42)
    samples <- rnorm(100)
    index <- seq(1:length(samples))
    df <- tibble(value = samples, index = index)
    
    bin_width <- 0.25
    
    count_data <- # some minor data transformation
      df %>%
      mutate(x = plyr::round_any(value, bin_width)) %>%
      group_by(x) %>%
      mutate(y = seq_along(x))
    
    plot <-
      ggplot(count_data, aes(group = index, x, y)) + # group by index is important
      geom_point(size = 5)
    
    p_anim <- 
      plot +
      transition_reveal(index)
    
    animate(p_anim, width = 550, height = 230, res = 96)
    

    geom_ellipse (Full control of point size)

    library(ggforce)
    plot2 <- 
      ggplot(count_data) +
      geom_ellipse(aes(group = index, x0 = x, y0 = y, a = bin_width/2, b = 0.5, angle = 0), fill = 'black') +
      coord_equal(bin_width) # to make the dots look nice and round
    
    p_anim2 <- 
      plot2 +
      transition_reveal(index) 
    
    animate(p_anim2) 
    

    update in the link which you provide to thomas's amazing example, you can see that he uses a similar approach - he uses geom_circle instead of geom_ellipse, which I chose because of better control for both vertical and horizontal radius.

    To get the "falling drops" effect, you will need transition_states and a long duration and many frames per second.

    p_anim2 <- 
      plot2 +
      transition_states(states = index, transition_length = 100, state_length = 1) +
      shadow_mark() +
      enter_fly(y_loc = 12) 
    
    animate(p_anim2, fps = 40, duration = 20) 
    

    Created on 2020-04-29 by the reprex package (v0.3.0)

    some inspiration from: ggplot dotplot: What is the proper use of geom_dotplot?

提交回复
热议问题