rlabuonora.com

El estilo de Metallica a lo largo de los discos

Para este post de #tidytuesday usé la API de spotify para bajar datos sobre la música de Metallica.

Este es el código para bajar los datos y la tapa de los discos. Faltaría explicar un poco más.

library(spotifyr)
library(tidyverse)
library(lubridate)


METALLICA_ID <- "2ye2Wgw4gimLv2eAKyk1NB"
metallica_albums <- get_artist_albums(id=METALLICA_ID,
                                      include_groups = "album",
                                      limit = 50) %>%
  slice(6, 11, 13, 17, 19, 21, 26, 30, 35, 39, 43) %>% 
  mutate(release_year = year(as_date(release_date)))


metallica_albums$cover_url <- metallica_albums$images %>% 
  purrr::map("url") %>% 
  purrr::map(3)


metallica_albums <- metallica_albums %>% 
  select(album_name=name, album_id=id, release_year, cover_url) 
  

get_album_tracks <- function(album_id, album_name) {
  # get track name, track id & album name (add all album.level data here)
  album <- get_album(id=album_id)
  tibble(track_name=album$tracks$items$name,
         track_id   = album$tracks$items$id,
         album_name = album_name)
}

get_track_info <- function(track_id, track_name, album_name) {
  features <- get_track_audio_features(id=track_id)
  mutate(features, 
         album_name = album_name,
         track_name = track_name) %>% 
    select(album_name, track_name, danceability:tempo, duration_ms)
}


metallica_tracks <- metallica_albums %>% 
  pmap(function(...) {
    current <- tibble(...)
    get_album_tracks(current$album_id, current$album_name)
  }) %>% 
  map(purrr::transpose) %>% 
  flatten %>% 
  map_df(function(x) {
    get_track_info(x$track_id, x$track_name, x$album_name)
  }) 

metallica_tracks_df <- metallica_tracks %>% 
  left_join(metallica_albums) %>% 
  mutate(track_name = str_remove(track_name, " - Remastered")) %>% 
  mutate(track_name = str_remove(track_name, "\\(Remastered\\)")) %>%
  mutate(album_name = str_remove(album_name, "\\(Remastered\\)")) %>% 
  group_by(album_name) %>% 
  mutate(track_num = row_number()) %>% 
  arrange(release_year, track_num)

dir.create('data')
saveRDS(metallica_tracks_df, file="data/metallica.rds")

download_cover <- function(url, release_year) {
  file_name <- glue::glue("{release_year}.jpg")
  dest <- file.path("covers", file_name)
  download.file(url, destfile=dest)
}

dir.create('covers')
purrr::walk2(metallica_albums$cover_url,
            metallica_albums$release_year, 
            download_cover)

Y este es el código para crear el gráfico:

# Evolution of song tempo

library(tidyverse)
library(ggplot2)
library(jpeg)
library(grid)
library(ggdark)
library(showtext)
library(ggrepel)

theme_set(dark_theme_grey())

# Agregar fuente
font_add_google("Metal Mania", "metal")
showtext_auto()

metallica <- readRDS("./data/metallica.rds")


# metallica$track_name <- fct_inorder(factor(metallica$track_name))
metallica$album_name <- fct_inorder(factor(metallica$album_name))

fast_songs <- c("Holier Than Thou", 
                "My Apocalypse", 
                "The Four Horsemen")

highligts <- metallica %>% 
  filter(track_name %in%  fast_songs)

# Gráfico de base.
tempo <- metallica %>% 
  ggplot(aes(album_name, tempo, group = 1)) + 
  scale_x_discrete(breaks = NULL, expand=c(0.1, 0)) +
  scale_y_continuous(limits = c(60, 220)) +
  geom_point() +
  geom_text_repel(data = highligts, 
                  aes(label=track_name), 
                  nudge_y = 10,
                  nudge_x = .2,
                  color="white", size = 3) +
  geom_smooth(se=FALSE) + 
  guides(color=FALSE) + 
  labs(title="Metallica", 
       subtitle = "New albums are almost as fast as the early ones.", 
       caption  = "Data: Spotify",
       x="Album", y="Tempo (bpm)")

# Agregar las tapas de los discos como imágenes.
covers <- list.files('covers', full.names = TRUE) %>% 
  purrr::map(readJPEG) %>% 
  purrr::map(rasterGrob, interpolate=TRUE)

y_coord_cover <-  60
y_offset <- 10.5


for (i in seq_along(covers)) {
  tempo <- tempo +  annotation_custom(grob=covers[[i]], xmin=i-1+.5, xmax=i+.5, ymin=y_coord_cover, ymax=y_coord_cover+y_offset)
}

tempo + 
  theme(
    text = element_text(family="metal"),
    plot.title = element_text(hjust = .5),
    plot.subtitle = element_text(hjust=.5)
  ) +
  ggsave("metallica_tempo.png")