Skip to content

Instantly share code, notes, and snippets.

@northernjamie
Created March 4, 2021 22:20
Show Gist options
  • Save northernjamie/e9008f4695a0521b02d168bc5ad510ca to your computer and use it in GitHub Desktop.
Save northernjamie/e9008f4695a0521b02d168bc5ad510ca to your computer and use it in GitHub Desktop.
r script for processing the data for the spinning hex visualisation
library(tidyverse)
library(colorspace)
library(audio)
options(scipen=100)
# get the international data from Our World in Data (already downloaded)
international_data <- read_csv("data/owid_international_2021_02_26.csv")
# G20 countries (actually 19 becuase of the EU)
g20_countries <- c("ARG","AUS","BRA","CAN","CHN","FRA","DEU","IND",'IDN',"ITA","JPN","MEX","RUS","SAU","ZAF","KOR","TUR","GBR","USA")
g20_countries_df <- data.frame(g20_countries)
# filter the full dataset to just g19 countries and the fields we want
g20_data <- international_data %>%
filter(iso_code %in% g20_countries) %>%
select(location,iso_code,date,total_cases_per_million,new_cases_per_million, new_cases_smoothed_per_million) %>%
mutate(date = as.Date(date, format = "%d/%m/%Y")) %>%
mutate(row_id = row_number()) %>%
mutate(new_cases_per_million = coalesce(new_cases_per_million,0)) %>%
mutate(total_cases_per_million = coalesce(total_cases_per_million,0)) %>%
mutate(new_cases_smoothed_per_million = coalesce(new_cases_smoothed_per_million,0)) %>%
mutate(new_cases_per_million = ifelse(new_cases_per_million >=0,new_cases_per_million,0)) %>%
mutate(total_cases_per_million = ifelse(total_cases_per_million >=0, total_cases_per_million,0)) %>%
mutate(new_cases_smoothed_per_million = ifelse(new_cases_smoothed_per_million >= 0, new_cases_smoothed_per_million,0)) %>%
mutate(date_country_id = paste0(date,iso_code))
# populate all non-included dates with zeros
unique_dates <- data.frame(unique(g20_data$date))
unique_countries <- data.frame(unique(g20_data$iso_code))
perms <- unique_dates %>%
full_join(unique_countries, by = character()) %>%
mutate(total_cases_per_million = 0.000) %>%
mutate(new_cases_per_million = 0.000) %>%
mutate(new_cases_smoothed_per_million = 0.000) %>%
mutate(date_country_id = paste0(unique.g20_data.date.,unique.g20_data.iso_code.)) %>%
filter(!date_country_id %in% g20_data$date_country_id) %>%
rename(iso_code = unique.g20_data.iso_code. ) %>%
rename(date = unique.g20_data.date. ) %>%
bind_rows(g20_data)
g20_data <- perms
# get the colours into the dataframe
pal <- heat.colors(10)
color_chart <- ggplot(data = g20_data) +
geom_bar(stat = 'identity',aes(date_country_id,new_cases_smoothed_per_million,fill=new_cases_smoothed_per_million)) +
scale_fill_gradientn(colours = pal)
color_chart
viz_colours <- ggplot_build(color_chart)$data[[1]]
viz_colours <- viz_colours %>%
select(fill,y) %>%
distinct()
max_new_cases_smoothed_per_million <- max(g20_data$new_cases_smoothed_per_million)
# loop through and make the text files needed to paste into After Effects
for (i in g20_countries) {
country = i
g20_hex_viz_data <- g20_data %>%
left_join(viz_colours, by = c('new_cases_smoothed_per_million' = 'y')) %>%
rename(rate_hex = fill) %>%
distinct() %>%
filter(iso_code == country) %>%
mutate(frame_start = 0 + (15*row_number())) %>%
mutate(rate_hex_r = strtoi(paste0('0x',(substr(rate_hex,2,3))))) %>%
mutate(rate_hex_g = strtoi(paste0('0x',(substr(rate_hex,4,5))))) %>%
mutate(rate_hex_b = strtoi(paste0('0x',(substr(rate_hex,6,7))))) %>%
mutate(colour_expression = paste0("\t",frame_start,'\t',"255",'\t',rate_hex_r,'\t',rate_hex_g,'\t',rate_hex_b)) %>%
mutate(rotation_mult = ceiling(total_cases_per_million)*0.001) %>%
mutate(rotation = rotation_mult*360) %>%
mutate(rotation_expression = paste0("\t",frame_start,"\t",rotation)) %>%
mutate(glow = (new_cases_smoothed_per_million/max_new_cases_smoothed_per_million) * 2 ) %>%
mutate(glow_expression = paste0("\t",frame_start,'\t',glow))
#make the text files for the rotation
rotation_expression_col <- g20_hex_viz_data %>%
select(rotation_expression) %>%
add_row(rotation_expression = "Adobe After Effects 8.0 Keyframe Data", .before= 1) %>%
add_row(rotation_expression = "", .after=1) %>%
add_row(rotation_expression = "\tUnits Per Second\t60", .after=2) %>%
add_row(rotation_expression = "\tSource Width\t1920", .after=3) %>%
add_row(rotation_expression = "\tSource Height\t1080", .after=4) %>%
add_row(rotation_expression = "\tSource Pixel Aspect Ratio\t1", .after=5) %>%
add_row(rotation_expression = "\tComp Pixel Aspect Ratio\t1", .after=6) %>%
add_row(rotation_expression = "", .after=7) %>%
add_row(rotation_expression = "Transform\tRotation", .after=8) %>%
add_row(rotation_expression = "\tFrame\tDegrees", .after=9) %>%
add_row(rotation_expression = "") %>%
add_row(rotation_expression = "End of Keyframe Data")
write_tsv(rotation_expression_col,paste0("outputs/g20_hex_viz/",country,"_rotation_expression.tsv"),col_names = FALSE, quote_escape = F)
#make the text files for the colour
colour_expression_col <- g20_hex_viz_data %>%
select(colour_expression) %>%
add_row(colour_expression = "Adobe After Effects 8.0 Keyframe Data", .before= 1) %>%
add_row(colour_expression = "", .after=1) %>%
add_row(colour_expression = "\tUnits Per Second\t60", .after=2) %>%
add_row(colour_expression = "\tSource Width\t1920", .after=3) %>%
add_row(colour_expression = "\tSource Height\t1080", .after=4) %>%
add_row(colour_expression = "\tSource Pixel Aspect Ratio\t1", .after=5) %>%
add_row(colour_expression = "\tComp Pixel Aspect Ratio\t1", .after=6) %>%
add_row(colour_expression = "", .after=7) %>%
add_row(colour_expression = "Effects\tSaber #1\tGlow Color #4", .after=8) %>%
add_row(colour_expression = "\tFrame\talpha \tred \tgreen \tblue ", .after=9) %>%
add_row(colour_expression = "") %>%
add_row(colour_expression = "End of Keyframe Data")
write_tsv(colour_expression_col,paste0("outputs/g20_hex_viz/",country,"_colour_expression.tsv"),col_names = FALSE, quote_escape = F)
#make the text files for the glow
glow_expression_col <- g20_hex_viz_data %>%
select(glow_expression) %>%
add_row(glow_expression = "Adobe After Effects 8.0 Keyframe Data", .before= 1) %>%
add_row(glow_expression = "", .after=1) %>%
add_row(glow_expression = "\tUnits Per Second\t60", .after=2) %>%
add_row(glow_expression = "\tSource Width\t1920", .after=3) %>%
add_row(glow_expression = "\tSource Height\t1080", .after=4) %>%
add_row(glow_expression = "\tSource Pixel Aspect Ratio\t1", .after=5) %>%
add_row(glow_expression = "\tComp Pixel Aspect Ratio\t1", .after=6) %>%
add_row(glow_expression = "", .after=7) %>%
add_row(glow_expression = "Effects\tSaber #1\tGlow Bias #7", .after=8) %>%
add_row(glow_expression = "\tFrame", .after=9) %>%
add_row(glow_expression = "") %>%
add_row(glow_expression = "End of Keyframe Data")
write_tsv(glow_expression_col,paste0("outputs/g20_hex_viz/",country,"_glow_expression.tsv"),col_names = FALSE, quote_escape = F)
}
# sonify the data
for (i in g20_countries) {
country <- i
music_dataset <- g20_data %>%
mutate(max_value = max(new_cases_smoothed_per_million)) %>%
filter(iso_code == i) %>%
mutate(alt_piano_note = (new_cases_smoothed_per_million/max_value)) %>%
mutate(piano_note = ntile(new_cases_smoothed_per_million,88)) %>%
mutate(frequency = 2 ^ ((piano_note-60)/12)*440) %>%
mutate(alt_frequency = (alt_piano_note * 440)+220) %>%
mutate(duration = 1)
tempo <- 240# set the tempo - this must must be 60 x the fps of the animated line chart for them to match up
sample_rate <- 44100
make_sine <- function(freq, duration) {
wave <- sin(seq(0, duration / tempo * 60, 1 / sample_rate) *
freq * 2 * pi)
fade <- seq(0, 1, 50 / sample_rate)
wave * c(fade, rep(1, length(wave) - 2 * length(fade)), rev(fade))
}
covid_wave <-
mapply(make_sine, music_dataset$alt_frequency, music_dataset$duration)
#play(covid_wave)
save.wave(covid_wave,paste0("outputs/g20_hex_viz/",i,"_cases_240bpm_2021_03_01.wav"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment