Advertisement
Guest User

city_race_chart

a guest
Mar 21st, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 3.71 KB | None | 0 0
  1. library(tidyverse)
  2. library(gganimate)
  3. library(tweenr)
  4. library(stringi)
  5. library(countrycode)
  6.  
  7. #read in data
  8. #see JBM's original post for links
  9. data <- read.csv("./city_populations.csv",
  10.                  encoding = "UTF-8", stringsAsFactors = FALSE) %>%
  11.   #select out relevant columns
  12.   select(country_id = Country.Code, country = Country.or.area,
  13.          city_id = City.Code, city = Urban.Agglomeration,
  14.          X1950, X1955, X1960, X1965, X1970, X1975, X1980, X1985, X1990,
  15.          X1995, X2000, X2005, X2010, X2015, X2020, X2025, X2030) %>%
  16.   #melt the data to long format
  17.   reshape2::melt(id.vars = c("country_id", "country", "city_id", "city"),
  18.                  variable.name = "year", value.name = "population") %>%
  19.   #conver the data into usuable numbers
  20.   mutate(year = as.numeric(gsub("^X", "", year)),
  21.          population = as.numeric(gsub(",", "", population)),
  22.          #convert the text into utf-8 readable
  23.          city = stri_trans_general(city, "latin-ascii")) %>%
  24.   #extract the english names for cities
  25.   mutate(city_name = case_when(
  26.     grepl("\\(", city) ~ str_extract(city,  "(?<=\\().+?(?=\\))"),
  27.     grepl("-", city) ~ gsub("-.*", "", city),
  28.     TRUE ~ as.character(city)
  29.   )) %>%
  30.   #group by and find order at any point
  31.   group_by(year) %>%
  32.   arrange(-population) %>%
  33.   mutate(order = row_number()) %>%
  34.   ungroup()
  35.  
  36. #get the id data for each unique city
  37. id_data <- data %>%
  38.   select(city_id, city_name, country_id, country) %>%
  39.   unique() %>%
  40.   #find the continent of each city
  41.   mutate(continent = countrycode(.$country, origin = "country.name", destination = "continent"))
  42.  
  43. #the number of frames the output will contain
  44. frames <- 100
  45.  
  46. #use tweenr to manually make the naimation frame data
  47. frame_data <- data %>%
  48.   group_by(year) %>%
  49.   arrange(-population) %>%
  50.   mutate(order = row_number()) %>%
  51.   #tweenr stuff here
  52.   select(city_id, year, population, order) %>%
  53.   mutate(ease = "linear") %>%
  54.   tween_elements(., "year", "city_id", "ease", nframes= frames) %>%
  55.   #select out columns
  56.   select(population, order, year, .frame, city_id = .group) %>%
  57.   #merge in id data
  58.   merge(., id_data, by = 'city_id') %>%
  59.   #munger population numbers
  60.   mutate(pop = round(population/1000, 2))
  61.  
  62. p <- frame_data %>%
  63.   #only want to plot the top 10
  64.   filter(order < 10.8) %>%
  65.   ggplot(aes(y = order, x = pop)) +
  66.   #hack to plot the moving bars
  67.   #from v helpful answer at
  68.   #https://stackoverflow.com/questions/53162821/
  69.   #animated-sorted-bar-chart-with-bars-overtaking-each-other/53163549
  70.   geom_tile(aes(x = pop/2, width = pop, fill = continent),
  71.             alpha = 0.8, colour = "black", height = 0.9) +
  72.   geom_text(aes(label = sprintf("%1.2f",pop)), hjust = 1) +
  73.   geom_text(aes(x = 0, label = paste(city_name, " ")),
  74.             vjust = 0.2, hjust = 1) +
  75.   #add labels to plot
  76.   labs(title='{round(as.numeric(closest_state))}',
  77.        x = "Population (millions)", y = "") +
  78.   #y limits at 0-10.5
  79.   #don't clip as will screw the labels outside the plot
  80.   coord_cartesian(ylim = c(0,10.5), clip = "off") +
  81.   #flip the y axis
  82.   scale_y_reverse(position = "left") +
  83.   #theme stuff
  84.   #taken from same stackoverflow answer
  85.   theme_minimal() +
  86.   theme(plot.title = element_text(hjust = 0, size = 22),
  87.         axis.ticks.y = element_blank(),
  88.         axis.text.y  = element_blank(),
  89.         #make sure labels will be visible
  90.         plot.margin = margin(0,0,0,2.5, "cm")) +
  91.   #transition by our calculated year
  92.   transition_states(year, transition_length = 1, state_length = 0) +
  93.   #scale x axis as pop increases
  94.   view_follow(fixed_y = TRUE) +
  95.   #fade as bares enter and exit the plot
  96.   exit_fade() +
  97.   enter_fade()
  98.  
  99. #save the gif
  100. gif <- animate(p, frames)
  101. anim_save("city_gif.gif", gif)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement