Animated sorted bar chart: problem with overlapping bars

前端 未结 2 446
余生分开走
余生分开走 2021-02-10 04:22

I created an animated bar chart which displays the scored goals by some players. Below the whole code is displayed how I came to the output.

The animation works as wishe

2条回答
  •  抹茶落季
    2021-02-10 04:44

    A simpler solution: you just need the rank to be the order of both goals and players' name (no need to remember rank last week or worry about the number of players - as long as their names are different, the bars won't be overlapped)

    library(tidyverse)
    library(gganimate)
    theme_set(theme_classic())
    
    df <- data.frame(Player = rep(c("Aguero", "Salah", "Aubameyang", "Kane"), 6), 
                     Team = rep(c("ManCity", "Liverpool", "Arsenal", "Tottenham"), 6), 
                     Gameday = c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6),
                     Goals = c(0,1,2,0,1,1,3,1,2,1,3,2,2,2,4,3,3,2,4,5,5,3,5,6),
                     stringsAsFactors = F)
    
    gap <- df %>%
      group_by(Gameday) %>%
      mutate(rank1 = min_rank(-Goals) * 1,
             Value_rel = Goals/Goals[rank1==1],
             Value_lbl = paste0(" ", Goals)) %>%
      filter(rank1 <=10) %>%
      ungroup() %>%
      
      group_by(Gameday) %>%
      arrange(rank1, Player) %>%
      mutate(rank = seq(1, n())) %>%
      ungroup() 
    
    p <- ggplot(gap, aes(rank, group = Player, stat = "identity",
                         fill = as.factor(Player), color = as.factor(Player))) +
      geom_tile(aes(y = Goals/2,
                    height = Goals,
                    width = 0.9), alpha = 0.8, color = NA) +
      geom_text(aes(y = 0, label = paste(Player, " ")), vjust = 0.2, hjust = 1) +
      geom_text(aes(y=Goals,label = Value_lbl, hjust=0)) +
      coord_flip(clip = "off", expand = FALSE) +
      scale_y_continuous(labels = scales::comma) +
      scale_x_reverse() +
      guides(color = FALSE, fill = FALSE) +
      labs(title = "Gameday {closest_state}", x="", y = "Goals scored") +
      theme(plot.title = element_text(hjust = 0, size = 22),
            axis.ticks.y = element_blank(),  # These relate to the axes post-flip
            axis.text.y  = element_blank(),  # These relate to the axes post-flip
            plot.margin = margin(1,1,1,4, "cm")) +
      transition_states(Gameday, transition_length = 4, state_length = 1) +
      ease_aes('cubic-in-out')
    
    p
    

提交回复
热议问题