{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Music Through The Ages: Billboard Top 100 Charts Analysis\n",
"\n",
"Frank Chen\n",
"\n",
"Data 512 Fall 2019\n",
"\n",
"## Introduction\n",
"\n",
"I analyzed Billboard Hot 100 Weekly Charts from 1958 to 2019 to show the relationship between popularity vs. relevance, velocity climb to #1 vs. #1 streak, as well as Billboard peak position vs. corresponding YouTube music video views. I show that songs from the 2010s are not outperforming the songs from the past, and confirmed that YouTube views do have correlations with higher Billboard peak positions, but noted that is already a confounding factor.\n",
"\n",
"As someone who is constantly looking for new music to listen to, I definitely discovered some new songs from this research. I believe this type of analysis would be interesting to historians, ethnographers, anthropologists, music enthusiasts, and even music managers, since it provides a data-driven approach to understanding how music popularity evolves as society evolves, and vice versa.\n",
"\n",
"## Background & Related Work\n",
"\n",
"Throughout history, music has consistently been used as one of the cultural indicators of society, in addition to literature, art, and film. The Billboard Charts have been calculating top performing songs since the 1930s [[1](https://www.wikiwand.com/en/Billboard_charts)], and serves as one of the indicators of successful songs. In recent years, with the introduction of social media platforms such as Facebook, Instagram, YouTube, and TikTok, there now exists strategies for making a song go viral [[2](https://www.grammy.com/grammys/news/what-music-goes-viral-tiktok)]. However, streaming platforms are only one part of the complex formular used in calculating Billboard Top 100. My main motivation for this project is to answer the question: Are today's (2010s) music exceeding the Billboard performances of music from the past?\n",
"\n",
"There are been many related work analyzing Billboard charts and music that topped the Billboard charts. The Billboard website has several blogs on this topic, including its analysis on digital song sale and chart beat, the website's blogs about top-performing songs [[3](https://www.billboard.com/charts/digital-song-sales)][[4](https://www.billboard.com/chart-beat)]. In addition, others have tried combining this Billboard Charts dataset with another dataset such as Spotify to analyze song preference changes in society, such as this blog post from Towards Data Science [[5](https://towardsdatascience.com/billboard-hot-100-analytics-using-data-to-understand-the-shift-in-popular-music-in-the-last-60-ac3919d39b49)].\n",
"\n",
"## Research Questions\n",
"\n",
"We will be dividing out analysis into 3 sections, aiming to answer the 3 questions:\n",
"\n",
"**I. How are song popularity and relevance related in the Billboard charts?**\n",
"\n",
"**II. How are song velocity and no. 1 streak related in the Billboard charts?**\n",
"\n",
"**III. How does other streaming platforms such as YouTube influence Billboard charts?**\n",
"\n",
"### Definitions\n",
"\n",
"- **Popularity**: how long the song stayed at no. 1 given all the weeks the song stayed on the chart. We represent this as the percentage of no. 1 counts over the total number of weeks the song spent on chart.\n",
"- **Relevance**: how long the song stayed in the Billboard charts. We represent this as the total number of weeks the song spent on the chart.\n",
"- **Velocity**: how many weeks did it take the song to reach no. 1 on Billboard\n",
"- **#1 Streak**: how many weeks did the song stay at no. 1 on Billboard\n",
"\n",
"## The Data\n",
"\n",
"In this analysis, I will be using two datasets (both in CSV format, and can be found in `raw_data/` folder). Both datasets are labeled as public domain data. More details about CC0 licenses can be found [here](https://creativecommons.org/publicdomain/zero/1.0/).\n",
"\n",
"[**Billboard Weekly Charts Data**](https://data.world/kcmillersean/billboard-hot-100-1958-2017): Weekly Hot 100 singles chart from August 1958 to June 2019 (317795 rows, 10 columns)\n",
"\n",
"> url, WeekID, Week Position, Song, Performer, SongID, Instance, Previous Week Position, Peak Position, Weeks on Chart\n",
"\n",
"[**YouTube Trending Video Data**](https://www.kaggle.com/datasnaek/youtube-new): Daily trending YouTube videos from Nov 2017 - May 2018 (40949 rows, 16 columns)\n",
"\n",
"Since I plan on joining this data with the Billboards data to connect music to views, the only columns I will be using in the YouTube dataset are:\n",
"\n",
"> title, channel_title, views\n",
"\n",
"## Methodology\n",
"\n",
"Methods used in this analysis: pivot table, joins, duplicate removals, lambdas, merge on substring matches. Specific methods are highlighted with links to stackoverflow guidance in the comments. I used `pandas` for the data transformations, and `plotly` for the visualization.\n",
"\n",
"I wanted to ensure my results were generated from the same input dataset without overlapping transformations, so I will first perform some initial data cleaning, then use the cleaned data for the rest of the analysis; they will be split into 3 sections to answer the 3 research questions. Please continue to see each section in detail, split into 3 parts: data preparation, data visualization, and data analysis."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initial Data Cleaning\n",
"\n",
"We first load the raw data, then do initial data cleaning: separate the `WeekID` field into `month`, `day`, `year` for easier analysis in the future"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# import all libraries\n",
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"# standard plotly imports\n",
"import plotly.graph_objects as go"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# load raw data\n",
"bboard_data = pd.read_csv('../raw_data/hot_100.csv')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" url | \n",
" WeekID | \n",
" Week Position | \n",
" Song | \n",
" Performer | \n",
" SongID | \n",
" Instance | \n",
" Previous Week Position | \n",
" Peak Position | \n",
" Weeks on Chart | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" http://www.billboard.com/charts/hot-100/1990-0... | \n",
" 2/10/1990 | \n",
" 75 | \n",
" Don't Wanna Fall In Love | \n",
" Jane Child | \n",
" Don't Wanna Fall In LoveJane Child | \n",
" 1 | \n",
" NaN | \n",
" 75 | \n",
" 1 | \n",
"
\n",
" \n",
" 1 | \n",
" http://www.billboard.com/charts/hot-100/1990-0... | \n",
" 2/17/1990 | \n",
" 53 | \n",
" Don't Wanna Fall In Love | \n",
" Jane Child | \n",
" Don't Wanna Fall In LoveJane Child | \n",
" 1 | \n",
" 75.0 | \n",
" 53 | \n",
" 2 | \n",
"
\n",
" \n",
" 2 | \n",
" http://www.billboard.com/charts/hot-100/1990-0... | \n",
" 2/24/1990 | \n",
" 43 | \n",
" Don't Wanna Fall In Love | \n",
" Jane Child | \n",
" Don't Wanna Fall In LoveJane Child | \n",
" 1 | \n",
" 53.0 | \n",
" 43 | \n",
" 3 | \n",
"
\n",
" \n",
" 3 | \n",
" http://www.billboard.com/charts/hot-100/1990-0... | \n",
" 3/3/1990 | \n",
" 37 | \n",
" Don't Wanna Fall In Love | \n",
" Jane Child | \n",
" Don't Wanna Fall In LoveJane Child | \n",
" 1 | \n",
" 43.0 | \n",
" 37 | \n",
" 4 | \n",
"
\n",
" \n",
" 4 | \n",
" http://www.billboard.com/charts/hot-100/1990-0... | \n",
" 3/10/1990 | \n",
" 27 | \n",
" Don't Wanna Fall In Love | \n",
" Jane Child | \n",
" Don't Wanna Fall In LoveJane Child | \n",
" 1 | \n",
" 37.0 | \n",
" 27 | \n",
" 5 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" url WeekID \\\n",
"0 http://www.billboard.com/charts/hot-100/1990-0... 2/10/1990 \n",
"1 http://www.billboard.com/charts/hot-100/1990-0... 2/17/1990 \n",
"2 http://www.billboard.com/charts/hot-100/1990-0... 2/24/1990 \n",
"3 http://www.billboard.com/charts/hot-100/1990-0... 3/3/1990 \n",
"4 http://www.billboard.com/charts/hot-100/1990-0... 3/10/1990 \n",
"\n",
" Week Position Song Performer \\\n",
"0 75 Don't Wanna Fall In Love Jane Child \n",
"1 53 Don't Wanna Fall In Love Jane Child \n",
"2 43 Don't Wanna Fall In Love Jane Child \n",
"3 37 Don't Wanna Fall In Love Jane Child \n",
"4 27 Don't Wanna Fall In Love Jane Child \n",
"\n",
" SongID Instance Previous Week Position \\\n",
"0 Don't Wanna Fall In LoveJane Child 1 NaN \n",
"1 Don't Wanna Fall In LoveJane Child 1 75.0 \n",
"2 Don't Wanna Fall In LoveJane Child 1 53.0 \n",
"3 Don't Wanna Fall In LoveJane Child 1 43.0 \n",
"4 Don't Wanna Fall In LoveJane Child 1 37.0 \n",
"\n",
" Peak Position Weeks on Chart \n",
"0 75 1 \n",
"1 53 2 \n",
"2 43 3 \n",
"3 37 4 \n",
"4 27 5 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bboard_data.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# use to_datetime to separate one column into multiple\n",
"bboard_data['WeekID'] = pd.to_datetime(bboard_data['WeekID'], format='%m/%d/%Y')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"bboard_data['year'] = bboard_data['WeekID'].dt.year\n",
"bboard_data['month'] = bboard_data['WeekID'].dt.month\n",
"bboard_data['day'] = bboard_data['WeekID'].dt.day\n",
"bboard_data.to_csv('tmp_data/cleaned_bboard_data.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"### I. How are song popularity and relevance related in the Billboard charts?\n",
"\n",
"This dataset provides potential for rich analysis into both the popularity **and** relevance of no. 1 songs on the Billboard charts.\n",
"\n",
"I will be preparing a marker chart that represents 3 dimensions of data: x-axis will show the songs, y-axis will show the popularity percentage of that song, and the data point itself will be a marker with area measuring the relevance of the song. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 1: Data Preparation"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read cleaned bboard_data\n",
"bboard_data = pd.read_csv('tmp_data/cleaned_bboard_data.csv')"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# use pivot table to extract counts of week positions for each song\n",
"# stackoverflow link: https://stackoverflow.com/questions/54527134/counting-column-values-based-on-values-in-other-columns-for-pandas-dataframes\n",
"bboard_data['count'] = 1\n",
"result = bboard_data.pivot_table(\n",
" index=['Song'], columns='Week Position', values='count',\n",
" fill_value=0, aggfunc=np.sum\n",
")\n",
"# save result to csv for future use\n",
"result.to_csv('tmp_data/bboard_song_position_count.csv')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read song_position_count.csv\n",
"song_position_count = pd.read_csv(\"tmp_data/bboard_song_position_count.csv\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# keep only the song and no. 1 column\n",
"song_position_count = song_position_count[['Song','1']]\n",
"song_position_count.to_csv('tmp_data/bboard_song_no1_count.csv')"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# join song_no1_count with bboard_data\n",
"song_no1_count = pd.read_csv('tmp_data/bboard_song_no1_count.csv')\n",
"bboard_data = pd.merge(bboard_data, song_no1_count, how='left', left_on='Song', right_on='Song')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# remove irrelevant columns\n",
"# stackoverflow link: https://stackoverflow.com/questions/14940743/selecting-excluding-sets-of-columns-in-pandas\n",
"bboard_data = bboard_data.drop(['Unnamed: 0_x', 'Unnamed: 0_y'], axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# clean rows to keep only entry for total weeks on chart\n",
"# stackoverflow link: https://stackoverflow.com/questions/50283775/python-pandas-keep-row-with-highest-column-value\n",
"bboard_data_tmp = bboard_data.sort_values('Weeks on Chart').drop_duplicates([\"Song\"],keep='last')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# clean columns to keep only data needed for visualization\n",
"bboard_data_tmp = bboard_data_tmp[['Song', 'Performer', 'Weeks on Chart', '1', 'year', 'month']]"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# rename column values\n",
"# stackoverflow link: https://stackoverflow.com/questions/11346283/renaming-columns-in-pandas\n",
"bboard_data_tmp.columns = ['Song', 'Performer', 'Relevance (Total Weeks on Chart)', 'Count of no. 1', 'Year', 'Month']\n",
"# calculate popularity\n",
"# stackoverflow link: https://stackoverflow.com/questions/26133538/round-a-single-column-in-pandas\n",
"bboard_data_tmp['Popularity'] = bboard_data_tmp['Count of no. 1']/bboard_data_tmp['Relevance (Total Weeks on Chart)']\n",
"bboard_data_tmp['Popularity'] = bboard_data_tmp['Popularity'].round(2)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [],
"source": [
"# add month and year to performer column for visualizing later\n",
"bboard_data_tmp['Performer'] = bboard_data_tmp.Performer.map(str) + \" (\" + bboard_data_tmp.Month.map(str) +\"-\" + bboard_data_tmp.Year.map(str) + \")\""
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# save to csv for future analysis\n",
"bboard_data_tmp.to_csv('tmp_data/bboard_song_pop_relevance.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 2: Data Visualization"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read in the data and drop unneeded column\n",
"bboard_song_pop_relevance = pd.read_csv('tmp_data/bboard_song_pop_relevance.csv')\n",
"bboard_song_pop_relevance = bboard_song_pop_relevance.drop(['Unnamed: 0'], axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# only use the top 100 songs that spent the most weeks on no. 1\n",
"bboard_song_pop_relevance_top100 = bboard_song_pop_relevance.nlargest(100, 'Count of no. 1')\n",
"bboard_song_pop_relevance_top100.to_csv('tmp_data/bboard_song_pop_relevance_top100.csv')\n",
"bboard_song_pop_relevance_top100 = bboard_song_pop_relevance_top100.sort_values(by=['Year'])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
" \n",
" "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hovertemplate": "%{x}
%{text}
Popularity: %{y}
Relevance: %{marker.size}",
"marker": {
"cmax": 70,
"cmin": 10,
"color": [
26,
21,
23,
15,
17,
19,
28,
23,
25,
20,
25,
26,
20,
19,
26,
27,
22,
21,
22,
25,
20,
29,
25,
32,
23,
30,
29,
29,
33,
30,
25,
20,
27,
34,
42,
60,
42,
20,
33,
27,
26,
58,
20,
28,
26,
32,
41,
23,
27,
30,
29,
32,
29,
45,
36,
38,
23,
39,
43,
36,
33,
29,
30,
49,
23,
32,
40,
31,
33,
56,
38,
29,
29,
41,
59,
42,
50,
48,
25,
39,
36,
44,
47,
36,
47,
36,
26,
56,
36,
52,
52,
27,
25,
22,
51,
36,
58,
21,
28,
15
],
"colorbar": {
"title": {
"text": "Relevance"
}
},
"colorscale": [
[
0,
"#000004"
],
[
0.1111111111111111,
"#180f3d"
],
[
0.2222222222222222,
"#440f76"
],
[
0.3333333333333333,
"#721f81"
],
[
0.4444444444444444,
"#9e2f7f"
],
[
0.5555555555555556,
"#cd4071"
],
[
0.6666666666666666,
"#f1605d"
],
[
0.7777777777777778,
"#fd9668"
],
[
0.8888888888888888,
"#feca8d"
],
[
1,
"#fcfdbf"
]
],
"line": {
"color": "LightGrey",
"width": 2
},
"size": [
26,
21,
23,
15,
17,
19,
28,
23,
25,
20,
25,
26,
20,
19,
26,
27,
22,
21,
22,
25,
20,
29,
25,
32,
23,
30,
29,
29,
33,
30,
25,
20,
27,
34,
42,
60,
42,
20,
33,
27,
26,
58,
20,
28,
26,
32,
41,
23,
27,
30,
29,
32,
29,
45,
36,
38,
23,
39,
43,
36,
33,
29,
30,
49,
23,
32,
40,
31,
33,
56,
38,
29,
29,
41,
59,
42,
50,
48,
25,
39,
36,
44,
47,
36,
47,
36,
26,
56,
36,
52,
52,
27,
25,
22,
51,
36,
58,
21,
28,
15
],
"sizeref": 1.2
},
"mode": "markers",
"text": [
"Bobby Darin (2-1960)",
"Percy Faith And His Orchestra (5-1960)",
"Bobby Lewis (9-1961)",
"The Beatles (4-1964)",
"Gladys Knight And The Pips (2-1968)",
"The Beatles (1-1969)",
"Frankie Avalon (4-1976)",
"Rod Stewart (3-1977)",
"Andy Gibb (9-1978)",
"Bee Gees (6-1978)",
"Debby Boone (2-1978)",
"Kim Carnes (9-1981)",
"Joan Jett & the Blackhearts (6-1982)",
"Paul McCartney And Stevie Wonder (8-1982)",
"Olivia Newton-John (3-1982)",
"Diana Ross & Lionel Richie (1-1982)",
"The Police (10-1983)",
"Van Halen (6-1984)",
"Bryan Adams (11-1991)",
"The Escape Club (11-1991)",
"Michael Jackson (4-1992)",
"UB40 (11-1993)",
"Snow (6-1993)",
"Boyz II Men (2-1993)",
"Janet Jackson (10-1993)",
"All-4-One (11-1994)",
"Mariah Carey (2-1994)",
"Montell Jordan (9-1995)",
"Boyz II Men (3-1995)",
"Madonna (7-1995)",
"Mariah Carey (3-1996)",
"Bone Thugs-N-Harmony (9-1996)",
"Mariah Carey & Boyz II Men (6-1996)",
"TLC (1-1996)",
"Toni Braxton (8-1997)",
"Los Del Rio (2-1997)",
"Elton John (7-1998)",
"Mariah Carey (1-1998)",
"Puff Daddy & Faith Evans Featuring 112 (1-1998)",
"Brandy & Monica (11-1998)",
"Santana Featuring The Product G&B (8-2000)",
"Santana Featuring Rob Thomas (9-2000)",
"Smash Mouth (12-2001)",
"Destiny's Child (3-2001)",
"Nelly (10-2002)",
"Ashanti (9-2002)",
"Mary J. Blige (5-2002)",
"Eminem (3-2003)",
"Beyonce Featuring Jay Z (11-2003)",
"50 Cent (8-2003)",
"Nelly Featuring Kelly Rowland (1-2003)",
"OutKast (5-2004)",
"Beyonce Featuring Sean Paul (2-2004)",
"Usher Featuring Lil Jon & Ludacris (11-2004)",
"Mario (6-2005)",
"Ciara Featuring Petey Pablo (3-2005)",
"50 Cent Featuring Olivia (7-2005)",
"Kanye West Featuring Jamie Foxx (4-2006)",
"Mariah Carey (2-2006)",
"Justin Timberlake (3-2007)",
"Rihanna Featuring Jay-Z (12-2007)",
"Justin Timberlake Featuring T.I. (4-2007)",
"Beyonce (5-2007)",
"Nickelback (1-2008)",
"Katy Perry (10-2008)",
"Soulja Boy Tell'em (3-2008)",
"Flo Rida Featuring T-Pain (8-2008)",
"T.I. (3-2009)",
"The Black Eyed Peas (11-2009)",
"The Black Eyed Peas (7-2010)",
"Ke$ha (7-2010)",
"Eminem Featuring Rihanna (1-2011)",
"Whitney Houston (3-2012)",
"Rihanna Featuring Calvin Harris (7-2012)",
"Gotye Featuring Kimbra (3-2013)",
"Maroon 5 (4-2013)",
"Carly Rae Jepsen (2-2013)",
"Robin Thicke Featuring T.I. + Pharrell (3-2014)",
"Michael Jackson (6-2014)",
"Iggy Azalea Featuring Charli XCX (12-2014)",
"Ellie Goulding (5-2014)",
"Lorde (5-2014)",
"Pharrell Williams (12-2014)",
"Taylor Swift (7-2015)",
"Meghan Trainor (6-2015)",
"Rihanna Featuring Drake (10-2016)",
"Adele (5-2016)",
"Mark Ronson Featuring Bruno Mars (3-2016)",
"Drake Featuring WizKid & Kyla (12-2016)",
"Wiz Khalifa Featuring Charlie Puth (3-2016)",
"The Chainsmokers Featuring Halsey (8-2017)",
"Rae Sremmurd Featuring Gucci Mane (4-2017)",
"Drake (10-2018)",
"Drake (12-2018)",
"Luis Fonsi & Daddy Yankee Featuring Justin Bieber (1-2018)",
"Drake (10-2018)",
"Ed Sheeran (3-2018)",
"Ariana Grande (6-2019)",
"Ariana Grande (5-2019)",
"Lil Nas X Featuring Billy Ray Cyrus (6-2019)"
],
"type": "scatter",
"x": [
"Mack The Knife",
"The Theme From \"A Summer Place\"",
"Tossin' And Turnin'",
"I Want To Hold Your Hand",
"I Heard It Through The Grapevine",
"Hey Jude",
"Venus",
"Tonight's The Night (Gonna Be Alright)",
"Shadow Dancing",
"Night Fever",
"You Light Up My Life",
"Bette Davis Eyes",
"I Love Rock 'N Roll",
"Ebony And Ivory",
"Physical",
"Endless Love",
"Every Breath You Take",
"Jump",
"(Everything I Do) I Do It For You",
"I'll Be There",
"Black Or White",
"Can't Help Falling In Love (From \"Sliver\")",
"Informer",
"End Of The Road (From \"Boomerang\")",
"That's The Way Love Goes",
"I Swear",
"Dreamlover",
"This Is How We Do It",
"I'll Make Love To You",
"Take A Bow",
"Fantasy",
"Tha Crossroads",
"One Sweet Day",
"Waterfalls",
"Un-Break My Heart",
"Macarena (Bayside Boys Mix)",
"Candle In The Wind 1997/Something About The Way You Look Tonight",
"Honey",
"I'll Be Missing You",
"The Boy Is Mine",
"Maria Maria",
"Smooth",
"I'm A Believer",
"Independent Women Part I",
"Hot In Herre",
"Foolish",
"Family Affair",
"Lose Yourself",
"Crazy In Love",
"In Da Club",
"Dilemma",
"Hey Ya!",
"Baby Boy",
"Yeah!",
"Let Me Love You",
"Goodies",
"Candy Shop",
"Gold Digger",
"We Belong Together",
"SexyBack",
"Umbrella",
"My Love",
"Irreplaceable",
"Rockstar",
"I Kissed A Girl",
"Crank That (Soulja Boy)",
"Low",
"Whatever You Like",
"Boom Boom Pow",
"I Gotta Feeling",
"TiK ToK",
"Love The Way You Lie",
"I Will Always Love You",
"We Found Love",
"Somebody That I Used To Know",
"One More Night",
"Call Me Maybe",
"Blurred Lines",
"Billie Jean",
"Fancy",
"Burn",
"Royals",
"Happy",
"Blank Space",
"All About That Bass",
"Work",
"Hello",
"Uptown Funk!",
"One Dance",
"See You Again",
"Closer",
"Black Beatles",
"Nice For What",
"In My Feelings",
"Despacito",
"God's Plan",
"Shape Of You",
"7 Rings",
"Thank U, Next",
"Old Town Road"
],
"y": [
0.35,
0.43,
0.3,
0.47,
0.41,
0.47,
0.25,
0.35,
0.28,
0.4,
0.4,
0.35,
0.35,
0.37,
0.38,
0.33,
0.36,
0.62,
0.32,
0.28,
0.35,
0.24,
0.28,
0.41,
0.35,
0.37,
0.28,
0.24,
0.42,
0.27,
0.32,
0.4,
0.59,
0.21,
0.26,
0.23,
0.33,
0.4,
0.33,
0.48,
0.38,
0.21,
0.35,
0.39,
0.27,
0.31,
0.22,
0.52,
0.3,
0.3,
0.34,
0.28,
0.31,
0.27,
0.25,
0.18,
0.39,
0.26,
0.33,
0.19,
0.21,
0.31,
0.33,
0.16,
0.3,
0.22,
0.25,
0.23,
0.36,
0.25,
0.24,
0.24,
0.48,
0.24,
0.14,
0.26,
0.18,
0.25,
0.28,
0.18,
0.22,
0.2,
0.21,
0.19,
0.17,
0.25,
0.46,
0.25,
0.28,
0.23,
0.23,
0.26,
0.32,
0.45,
0.31,
0.31,
0.21,
0.38,
0.25,
0.73
]
}
],
"layout": {
"autosize": false,
"height": 800,
"margin": {
"b": 300,
"l": 50,
"pad": 4,
"r": 50,
"t": 100
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Top 100 Billboard #1 Songs in terms of Relative Popularity & Relevance",
"x": 0.5,
"xanchor": "center",
"y": 0.9,
"yanchor": "top"
},
"width": 1000,
"xaxis": {
"tickangle": 45,
"title": {
"text": "Song"
}
},
"yaxis": {
"title": {
"text": "Popularity"
}
}
}
},
"text/html": [
"\n",
" \n",
" \n",
"
\n",
" \n",
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# create bubble chart\n",
"# stackoverflow link: https://plot.ly/python/bubble-charts/\n",
"# plotly colorscale: https://plot.ly/python/v3/matplotlib-colorscales/\n",
"fig = go.Figure()\n",
"\n",
"fig.add_trace(go.Scatter(\n",
" x=bboard_song_pop_relevance_top100['Song'],\n",
" y=bboard_song_pop_relevance_top100['Popularity'],\n",
" mode='markers',\n",
" marker=dict(\n",
" line=dict(width=2, color='LightGrey'),\n",
" size=16,\n",
" cmax=70,\n",
" cmin=10,\n",
" color=bboard_song_pop_relevance_top100['Relevance (Total Weeks on Chart)'],\n",
" colorbar=dict(\n",
" title=\"Relevance\"\n",
" ),\n",
" colorscale=\"magma\",\n",
" sizeref=2.*15/(5.**2)\n",
" ),\n",
" marker_size=bboard_song_pop_relevance_top100['Relevance (Total Weeks on Chart)'],\n",
" text=bboard_song_pop_relevance_top100['Performer'],\n",
" hovertemplate = \"%{x}
%{text}
Popularity: %{y}
Relevance: %{marker.size}\",\n",
"))\n",
"\n",
"fig.update_layout(\n",
" title={\n",
" 'text': \"Top 100 Billboard #1 Songs in terms of Relative Popularity & Relevance\",\n",
" 'y':0.9,\n",
" 'x':0.5,\n",
" 'xanchor': 'center',\n",
" 'yanchor': 'top'},\n",
" autosize=False,\n",
" width=1000,\n",
" height=800,\n",
" margin=go.layout.Margin(\n",
" l=50,\n",
" r=50,\n",
" b=300,\n",
" t=100,\n",
" pad=4\n",
" ))\n",
"fig.update_xaxes(title_text='Song')\n",
"fig.update_xaxes(tickangle=45)\n",
"fig.update_yaxes(title_text='Popularity')\n",
"\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 3: Findings - Data Analysis\n",
"\n",
"There are a few interesting observations to be made from the interactive chart above. \n",
"\n",
"First, we see that relatively, the most popular songs through the ages generally do not have as much relevance (they have a higher no. 1-vs-rest ratio on the billboard charts, but spend less weeks on the charts). \n",
"\n",
"Next, we see that relatively, no.1 Billboard ranking songs after the 2000s tend to have more relevance (they tend to spend more weeks on the charts than pre-2000 no. 1 songs). This may be due to some external factors such as the rise of YouTube music videos (more on this in the third section).\n",
"\n",
"Lastly, we see that the data points that stand out (the ones near the top) are the ones that have [high number of weeks spent in no. 1 position](https://www.billboard.com/articles/columns/chart-beat/6077132/hot-100-songs-longest-leading-no-1s). A clear example is 'Old Town Road', with `0.73` popularity score. There are some exceptions to this, including 'Despacito' and 'Uptown Funk!'.\n",
"\n",
"Next, we'll extract the top 10 songs. Songs from the 2010s only account for 4 out of the 10 songs in this list."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Song | \n",
" Performer | \n",
" Relevance (Total Weeks on Chart) | \n",
" Count of no. 1 | \n",
" Year | \n",
" Month | \n",
" Popularity | \n",
"
\n",
" \n",
" \n",
" \n",
" 15893 | \n",
" Old Town Road | \n",
" Lil Nas X Featuring Billy Ray Cyrus (6-2019) | \n",
" 15 | \n",
" 11 | \n",
" 2019 | \n",
" 6 | \n",
" 0.73 | \n",
"
\n",
" \n",
" 21056 | \n",
" Jump | \n",
" Van Halen (6-1984) | \n",
" 21 | \n",
" 13 | \n",
" 1984 | \n",
" 6 | \n",
" 0.62 | \n",
"
\n",
" \n",
" 22423 | \n",
" One Sweet Day | \n",
" Mariah Carey & Boyz II Men (6-1996) | \n",
" 27 | \n",
" 16 | \n",
" 1996 | \n",
" 6 | \n",
" 0.59 | \n",
"
\n",
" \n",
" 21625 | \n",
" Lose Yourself | \n",
" Eminem (3-2003) | \n",
" 23 | \n",
" 12 | \n",
" 2003 | \n",
" 3 | \n",
" 0.52 | \n",
"
\n",
" \n",
" 22685 | \n",
" I Will Always Love You | \n",
" Whitney Houston (3-2012) | \n",
" 29 | \n",
" 14 | \n",
" 2012 | \n",
" 3 | \n",
" 0.48 | \n",
"
\n",
" \n",
" 22376 | \n",
" The Boy Is Mine | \n",
" Brandy & Monica (11-1998) | \n",
" 27 | \n",
" 13 | \n",
" 1998 | \n",
" 11 | \n",
" 0.48 | \n",
"
\n",
" \n",
" 18585 | \n",
" Hey Jude | \n",
" The Beatles (1-1969) | \n",
" 19 | \n",
" 9 | \n",
" 1969 | \n",
" 1 | \n",
" 0.47 | \n",
"
\n",
" \n",
" 15469 | \n",
" I Want To Hold Your Hand | \n",
" The Beatles (4-1964) | \n",
" 15 | \n",
" 7 | \n",
" 1964 | \n",
" 4 | \n",
" 0.47 | \n",
"
\n",
" \n",
" 22304 | \n",
" Hello | \n",
" Adele (5-2016) | \n",
" 26 | \n",
" 12 | \n",
" 2016 | \n",
" 5 | \n",
" 0.46 | \n",
"
\n",
" \n",
" 21315 | \n",
" In My Feelings | \n",
" Drake (12-2018) | \n",
" 22 | \n",
" 10 | \n",
" 2018 | \n",
" 12 | \n",
" 0.45 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Song Performer \\\n",
"15893 Old Town Road Lil Nas X Featuring Billy Ray Cyrus (6-2019) \n",
"21056 Jump Van Halen (6-1984) \n",
"22423 One Sweet Day Mariah Carey & Boyz II Men (6-1996) \n",
"21625 Lose Yourself Eminem (3-2003) \n",
"22685 I Will Always Love You Whitney Houston (3-2012) \n",
"22376 The Boy Is Mine Brandy & Monica (11-1998) \n",
"18585 Hey Jude The Beatles (1-1969) \n",
"15469 I Want To Hold Your Hand The Beatles (4-1964) \n",
"22304 Hello Adele (5-2016) \n",
"21315 In My Feelings Drake (12-2018) \n",
"\n",
" Relevance (Total Weeks on Chart) Count of no. 1 Year Month \\\n",
"15893 15 11 2019 6 \n",
"21056 21 13 1984 6 \n",
"22423 27 16 1996 6 \n",
"21625 23 12 2003 3 \n",
"22685 29 14 2012 3 \n",
"22376 27 13 1998 11 \n",
"18585 19 9 1969 1 \n",
"15469 15 7 1964 4 \n",
"22304 26 12 2016 5 \n",
"21315 22 10 2018 12 \n",
"\n",
" Popularity \n",
"15893 0.73 \n",
"21056 0.62 \n",
"22423 0.59 \n",
"21625 0.52 \n",
"22685 0.48 \n",
"22376 0.48 \n",
"18585 0.47 \n",
"15469 0.47 \n",
"22304 0.46 \n",
"21315 0.45 "
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# extract the top 10 songs by popularity first, then relevance\n",
"bboard_song_pop_relevance_top100.sort_values(['Popularity', 'Relevance (Total Weeks on Chart)'], ascending=[False, False]).head(10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### II. How are song velocity and no. 1 streak related in the Billboard charts?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to analyzing song popularity and relevance, it is also important to understand the trend about a song's velocity and #1 streak.\n",
"\n",
"I will be preparing a marker chart that represents 3 dimensions of data: x-axis will show the songs, y-axis will show the velocity of the song, and the data point itself will be a marker with area measuring the #1 streak of the song.\n",
"\n",
"#### Step 1: Data Preparation"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read cleaned bboard_data\n",
"bboard_data = pd.read_csv('tmp_data/cleaned_bboard_data.csv')\n",
"# clean rows to keep only entry for first time the song reaches peak position\n",
"# stackoverflow link: https://stackoverflow.com/questions/50283775/python-pandas-keep-row-with-highest-column-value\n",
"bboard_data = bboard_data.sort_values(['Week Position', 'Weeks on Chart'], ascending=[True, True]).drop_duplicates([\"Song\"],keep='first')\n",
"# join cleaned dataframe with top 100 songs\n",
"bboard_data = pd.merge(bboard_song_pop_relevance_top100, bboard_data, how='left', left_on='Song', right_on='Song')\n",
"bboard_data = bboard_data[['Song','Performer_x', 'Count of no. 1', 'Year', 'Popularity', 'Weeks on Chart']]\n",
"bboard_data.columns = ['Song', 'Performer', 'no. 1 Streak', 'Year', 'Popularity', 'Weeks before no. 1']\n",
"bboard_data.to_csv('tmp_data/bboard_song_velocity_top100.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 2: Data Visualization"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hovertemplate": "%{x}
%{text}
Velocity: %{y}
#1 Streak: %{marker.size}",
"marker": {
"cmax": 15,
"cmin": 5,
"color": [
9,
9,
7,
7,
7,
9,
7,
8,
8,
10,
7,
9,
7,
7,
10,
9,
8,
13,
7,
7,
7,
8,
13,
7,
7,
11,
8,
7,
14,
8,
7,
8,
8,
16,
14,
11,
14,
8,
11,
13,
10,
12,
11,
7,
10,
9,
7,
10,
9,
8,
12,
9,
9,
12,
9,
7,
9,
10,
14,
10,
9,
7,
7,
8,
7,
7,
10,
7,
12,
14,
9,
7,
10,
14,
9,
8,
11,
12,
7,
7,
8,
9,
10,
8,
7,
12,
10,
12,
9,
14,
7,
12,
16,
11,
8,
10,
12,
7,
8,
11
],
"colorbar": {
"title": {
"text": "#1 Streak"
}
},
"colorscale": [
[
0,
"#440154"
],
[
0.1111111111111111,
"#482878"
],
[
0.2222222222222222,
"#3e4989"
],
[
0.3333333333333333,
"#31688e"
],
[
0.4444444444444444,
"#26828e"
],
[
0.5555555555555556,
"#1f9e89"
],
[
0.6666666666666666,
"#35b779"
],
[
0.7777777777777778,
"#6ece58"
],
[
0.8888888888888888,
"#b5de2b"
],
[
1,
"#fde725"
]
],
"line": {
"color": "DarkSlateGrey",
"width": 2
},
"size": [
9,
9,
7,
7,
7,
9,
7,
8,
8,
10,
7,
9,
7,
7,
10,
9,
8,
13,
7,
7,
7,
8,
13,
7,
7,
11,
8,
7,
14,
8,
7,
8,
8,
16,
14,
11,
14,
8,
11,
13,
10,
12,
11,
7,
10,
9,
7,
10,
9,
8,
12,
9,
9,
12,
9,
7,
9,
10,
14,
10,
9,
7,
7,
8,
7,
7,
10,
7,
12,
14,
9,
7,
10,
14,
9,
8,
11,
12,
7,
7,
8,
9,
10,
8,
7,
12,
10,
12,
9,
14,
7,
12,
16,
11,
8,
10,
12,
7,
8,
11
],
"sizeref": 0.6122448979591837
},
"mode": "markers",
"text": [
"Bobby Darin (2-1960)",
"Percy Faith And His Orchestra (5-1960)",
"Bobby Lewis (9-1961)",
"The Beatles (4-1964)",
"Gladys Knight And The Pips (2-1968)",
"The Beatles (1-1969)",
"Frankie Avalon (4-1976)",
"Rod Stewart (3-1977)",
"Bee Gees (6-1978)",
"Debby Boone (2-1978)",
"Andy Gibb (9-1978)",
"Kim Carnes (9-1981)",
"Joan Jett & the Blackhearts (6-1982)",
"Paul McCartney And Stevie Wonder (8-1982)",
"Olivia Newton-John (3-1982)",
"Diana Ross & Lionel Richie (1-1982)",
"The Police (10-1983)",
"Van Halen (6-1984)",
"Bryan Adams (11-1991)",
"The Escape Club (11-1991)",
"Michael Jackson (4-1992)",
"Janet Jackson (10-1993)",
"Boyz II Men (2-1993)",
"UB40 (11-1993)",
"Snow (6-1993)",
"All-4-One (11-1994)",
"Mariah Carey (2-1994)",
"Montell Jordan (9-1995)",
"Boyz II Men (3-1995)",
"Madonna (7-1995)",
"TLC (1-1996)",
"Mariah Carey (3-1996)",
"Bone Thugs-N-Harmony (9-1996)",
"Mariah Carey & Boyz II Men (6-1996)",
"Los Del Rio (2-1997)",
"Toni Braxton (8-1997)",
"Elton John (7-1998)",
"Mariah Carey (1-1998)",
"Puff Daddy & Faith Evans Featuring 112 (1-1998)",
"Brandy & Monica (11-1998)",
"Santana Featuring The Product G&B (8-2000)",
"Santana Featuring Rob Thomas (9-2000)",
"Destiny's Child (3-2001)",
"Smash Mouth (12-2001)",
"Ashanti (9-2002)",
"Mary J. Blige (5-2002)",
"Nelly (10-2002)",
"Nelly Featuring Kelly Rowland (1-2003)",
"50 Cent (8-2003)",
"Beyonce Featuring Jay Z (11-2003)",
"Eminem (3-2003)",
"OutKast (5-2004)",
"Beyonce Featuring Sean Paul (2-2004)",
"Usher Featuring Lil Jon & Ludacris (11-2004)",
"Mario (6-2005)",
"Ciara Featuring Petey Pablo (3-2005)",
"50 Cent Featuring Olivia (7-2005)",
"Kanye West Featuring Jamie Foxx (4-2006)",
"Mariah Carey (2-2006)",
"Beyonce (5-2007)",
"Justin Timberlake Featuring T.I. (4-2007)",
"Justin Timberlake (3-2007)",
"Rihanna Featuring Jay-Z (12-2007)",
"Nickelback (1-2008)",
"Katy Perry (10-2008)",
"Soulja Boy Tell'em (3-2008)",
"Flo Rida Featuring T-Pain (8-2008)",
"T.I. (3-2009)",
"The Black Eyed Peas (11-2009)",
"The Black Eyed Peas (7-2010)",
"Ke$ha (7-2010)",
"Eminem Featuring Rihanna (1-2011)",
"Rihanna Featuring Calvin Harris (7-2012)",
"Whitney Houston (3-2012)",
"Carly Rae Jepsen (2-2013)",
"Gotye Featuring Kimbra (3-2013)",
"Maroon 5 (4-2013)",
"Robin Thicke Featuring T.I. + Pharrell (3-2014)",
"Michael Jackson (6-2014)",
"Iggy Azalea Featuring Charli XCX (12-2014)",
"Ellie Goulding (5-2014)",
"Lorde (5-2014)",
"Pharrell Williams (12-2014)",
"Meghan Trainor (6-2015)",
"Taylor Swift (7-2015)",
"Wiz Khalifa Featuring Charlie Puth (3-2016)",
"Drake Featuring WizKid & Kyla (12-2016)",
"Adele (5-2016)",
"Rihanna Featuring Drake (10-2016)",
"Mark Ronson Featuring Bruno Mars (3-2016)",
"Rae Sremmurd Featuring Gucci Mane (4-2017)",
"The Chainsmokers Featuring Halsey (8-2017)",
"Luis Fonsi & Daddy Yankee Featuring Justin Bieber (1-2018)",
"Drake (10-2018)",
"Drake (10-2018)",
"Drake (12-2018)",
"Ed Sheeran (3-2018)",
"Ariana Grande (5-2019)",
"Ariana Grande (6-2019)",
"Lil Nas X Featuring Billy Ray Cyrus (6-2019)"
],
"type": "scatter",
"x": [
"Mack The Knife",
"The Theme From \"A Summer Place\"",
"Tossin' And Turnin'",
"I Want To Hold Your Hand",
"I Heard It Through The Grapevine",
"Hey Jude",
"Venus",
"Tonight's The Night (Gonna Be Alright)",
"Night Fever",
"You Light Up My Life",
"Shadow Dancing",
"Bette Davis Eyes",
"I Love Rock 'N Roll",
"Ebony And Ivory",
"Physical",
"Endless Love",
"Every Breath You Take",
"Jump",
"(Everything I Do) I Do It For You",
"I'll Be There",
"Black Or White",
"That's The Way Love Goes",
"End Of The Road (From \"Boomerang\")",
"Can't Help Falling In Love (From \"Sliver\")",
"Informer",
"I Swear",
"Dreamlover",
"This Is How We Do It",
"I'll Make Love To You",
"Take A Bow",
"Waterfalls",
"Fantasy",
"Tha Crossroads",
"One Sweet Day",
"Macarena (Bayside Boys Mix)",
"Un-Break My Heart",
"Candle In The Wind 1997/Something About The Way You Look Tonight",
"Honey",
"I'll Be Missing You",
"The Boy Is Mine",
"Maria Maria",
"Smooth",
"Independent Women Part I",
"I'm A Believer",
"Foolish",
"Family Affair",
"Hot In Herre",
"Dilemma",
"In Da Club",
"Crazy In Love",
"Lose Yourself",
"Hey Ya!",
"Baby Boy",
"Yeah!",
"Let Me Love You",
"Goodies",
"Candy Shop",
"Gold Digger",
"We Belong Together",
"Irreplaceable",
"My Love",
"SexyBack",
"Umbrella",
"Rockstar",
"I Kissed A Girl",
"Crank That (Soulja Boy)",
"Low",
"Whatever You Like",
"Boom Boom Pow",
"I Gotta Feeling",
"TiK ToK",
"Love The Way You Lie",
"We Found Love",
"I Will Always Love You",
"Call Me Maybe",
"Somebody That I Used To Know",
"One More Night",
"Blurred Lines",
"Billie Jean",
"Fancy",
"Burn",
"Royals",
"Happy",
"All About That Bass",
"Blank Space",
"See You Again",
"One Dance",
"Hello",
"Work",
"Uptown Funk!",
"Black Beatles",
"Closer",
"Despacito",
"God's Plan",
"Nice For What",
"In My Feelings",
"Shape Of You",
"Thank U, Next",
"7 Rings",
"Old Town Road"
],
"y": [
7,
7,
12,
3,
4,
3,
5,
7,
7,
7,
10,
8,
7,
6,
8,
6,
6,
4,
5,
4,
3,
3,
5,
11,
10,
5,
6,
8,
3,
5,
5,
1,
2,
1,
33,
7,
1,
1,
1,
2,
9,
13,
9,
4,
10,
5,
9,
6,
9,
8,
6,
9,
8,
8,
11,
12,
5,
8,
8,
7,
7,
8,
7,
4,
7,
8,
9,
3,
4,
3,
11,
4,
6,
3,
16,
15,
8,
8,
7,
12,
11,
13,
8,
9,
3,
5,
5,
1,
4,
8,
9,
3,
17,
1,
1,
2,
1,
1,
1,
5
]
}
],
"layout": {
"autosize": false,
"height": 800,
"margin": {
"b": 300,
"l": 50,
"pad": 4,
"r": 50,
"t": 100
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Top 100 Billboard #1 Songs in terms of Velocity and #1 Streak",
"x": 0.5,
"xanchor": "center",
"y": 0.9,
"yanchor": "top"
},
"width": 1000,
"xaxis": {
"tickangle": 45,
"title": {
"text": "Song"
}
},
"yaxis": {
"title": {
"text": "Velocity"
}
}
}
},
"text/html": [
"\n",
" \n",
" \n",
"
\n",
" \n",
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# create bubble chart\n",
"# stackoverflow link: https://plot.ly/python/bubble-charts/\n",
"# plotly colorscale: https://plot.ly/python/v3/matplotlib-colorscales/\n",
"bboard_song_velocity_top100 = pd.read_csv('tmp_data/bboard_song_velocity_top100.csv')\n",
"bboard_song_velocity_top100 = bboard_song_velocity_top100.sort_values(by=['Year'])\n",
"bboard_song_velocity_top100.head()\n",
"fig = go.Figure()\n",
"\n",
"fig.add_trace(go.Scatter(\n",
" x=bboard_song_velocity_top100['Song'],\n",
" y=bboard_song_velocity_top100['Weeks before no. 1'],\n",
" mode='markers',\n",
" marker=dict(\n",
" line=dict(width=2, color='DarkSlateGrey'),\n",
" size=15,\n",
" cmax=15,\n",
" cmin=5,\n",
" color=bboard_song_velocity_top100['no. 1 Streak'],\n",
" colorbar=dict(\n",
" title=\"#1 Streak\"\n",
" ),\n",
" colorscale=\"VIRIDIS\",\n",
" sizeref=2.*15/(7.**2),\n",
" ),\n",
" marker_size=bboard_song_velocity_top100['no. 1 Streak'],\n",
" text=bboard_song_velocity_top100['Performer'],\n",
" hovertemplate = \"%{x}
%{text}
Velocity: %{y}
#1 Streak: %{marker.size}\",\n",
"))\n",
"\n",
"fig.update_layout(\n",
" title={\n",
" 'text': \"Top 100 Billboard #1 Songs in terms of Velocity and #1 Streak\",\n",
" 'y':0.9,\n",
" 'x':0.5,\n",
" 'xanchor': 'center',\n",
" 'yanchor': 'top'},\n",
" autosize=False,\n",
" width=1000,\n",
" height=800,\n",
" margin=go.layout.Margin(\n",
" l=50,\n",
" r=50,\n",
" b=300,\n",
" t=100,\n",
" pad=4\n",
" ))\n",
"fig.update_xaxes(title_text='Song')\n",
"fig.update_xaxes(tickangle=45)\n",
"fig.update_yaxes(title_text='Velocity')\n",
"\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 3: Findings - Data Analysis\n",
"\n",
"There are (again) some interesting observations to be made from this visualization. Immediately, we see an outlier datapoint with a high count of weeks before reaching #1 (indicating low velocity). This song, 'Macarena', however, proceeded to spend 14 weeks at no. 1, an impressive feat. Another observation is the 1990s had many songs that reached #1 with fewer weeks than much of the songs in the 2000s. We see the pattern in the 1990s repeating again from the 2010s, with songs consistently spending less than 7-8 weeks to reach no. 1. This could be due to the additional factors added into the Billboard charting calculations, including YouTube streaming, as we will explore in the third section.\n",
"\n",
"Next, we'll extract the top 10 songs. Songs from the 2010s again only account for 4 out of the 10 songs in this list."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" Song | \n",
" Performer | \n",
" no. 1 Streak | \n",
" Year | \n",
" Popularity | \n",
" Weeks before no. 1 | \n",
"
\n",
" \n",
" \n",
" \n",
" 32 | \n",
" 32 | \n",
" One Sweet Day | \n",
" Mariah Carey & Boyz II Men (6-1996) | \n",
" 16 | \n",
" 1996 | \n",
" 0.59 | \n",
" 1 | \n",
"
\n",
" \n",
" 94 | \n",
" 94 | \n",
" Despacito | \n",
" Luis Fonsi & Daddy Yankee Featuring Justin Bie... | \n",
" 16 | \n",
" 2018 | \n",
" 0.31 | \n",
" 17 | \n",
"
\n",
" \n",
" 36 | \n",
" 36 | \n",
" Candle In The Wind 1997/Something About The Wa... | \n",
" Elton John (7-1998) | \n",
" 14 | \n",
" 1998 | \n",
" 0.33 | \n",
" 1 | \n",
"
\n",
" \n",
" 28 | \n",
" 28 | \n",
" I'll Make Love To You | \n",
" Boyz II Men (3-1995) | \n",
" 14 | \n",
" 1995 | \n",
" 0.42 | \n",
" 3 | \n",
"
\n",
" \n",
" 69 | \n",
" 69 | \n",
" I Gotta Feeling | \n",
" The Black Eyed Peas (7-2010) | \n",
" 14 | \n",
" 2010 | \n",
" 0.25 | \n",
" 3 | \n",
"
\n",
" \n",
" 72 | \n",
" 72 | \n",
" I Will Always Love You | \n",
" Whitney Houston (3-2012) | \n",
" 14 | \n",
" 2012 | \n",
" 0.48 | \n",
" 3 | \n",
"
\n",
" \n",
" 58 | \n",
" 58 | \n",
" We Belong Together | \n",
" Mariah Carey (2-2006) | \n",
" 14 | \n",
" 2006 | \n",
" 0.33 | \n",
" 8 | \n",
"
\n",
" \n",
" 87 | \n",
" 87 | \n",
" Uptown Funk! | \n",
" Mark Ronson Featuring Bruno Mars (3-2016) | \n",
" 14 | \n",
" 2016 | \n",
" 0.25 | \n",
" 8 | \n",
"
\n",
" \n",
" 35 | \n",
" 35 | \n",
" Macarena (Bayside Boys Mix) | \n",
" Los Del Rio (2-1997) | \n",
" 14 | \n",
" 1997 | \n",
" 0.23 | \n",
" 33 | \n",
"
\n",
" \n",
" 39 | \n",
" 39 | \n",
" The Boy Is Mine | \n",
" Brandy & Monica (11-1998) | \n",
" 13 | \n",
" 1998 | \n",
" 0.48 | \n",
" 2 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 Song \\\n",
"32 32 One Sweet Day \n",
"94 94 Despacito \n",
"36 36 Candle In The Wind 1997/Something About The Wa... \n",
"28 28 I'll Make Love To You \n",
"69 69 I Gotta Feeling \n",
"72 72 I Will Always Love You \n",
"58 58 We Belong Together \n",
"87 87 Uptown Funk! \n",
"35 35 Macarena (Bayside Boys Mix) \n",
"39 39 The Boy Is Mine \n",
"\n",
" Performer no. 1 Streak Year \\\n",
"32 Mariah Carey & Boyz II Men (6-1996) 16 1996 \n",
"94 Luis Fonsi & Daddy Yankee Featuring Justin Bie... 16 2018 \n",
"36 Elton John (7-1998) 14 1998 \n",
"28 Boyz II Men (3-1995) 14 1995 \n",
"69 The Black Eyed Peas (7-2010) 14 2010 \n",
"72 Whitney Houston (3-2012) 14 2012 \n",
"58 Mariah Carey (2-2006) 14 2006 \n",
"87 Mark Ronson Featuring Bruno Mars (3-2016) 14 2016 \n",
"35 Los Del Rio (2-1997) 14 1997 \n",
"39 Brandy & Monica (11-1998) 13 1998 \n",
"\n",
" Popularity Weeks before no. 1 \n",
"32 0.59 1 \n",
"94 0.31 17 \n",
"36 0.33 1 \n",
"28 0.42 3 \n",
"69 0.25 3 \n",
"72 0.48 3 \n",
"58 0.33 8 \n",
"87 0.25 8 \n",
"35 0.23 33 \n",
"39 0.48 2 "
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# extract the top 10 songs by no. 1 streak, then weeks before no. 1\n",
"bboard_song_velocity_top100.sort_values(['no. 1 Streak', 'Weeks before no. 1'], ascending=[False, True]).head(10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### III. How does other streaming platforms such as YouTube influence Billboard charts?\n",
"\n",
"In 2013, Billboard added YouTube streaming to its Hot 100 calculations ([link](https://www.billboard.com/articles/news/1549399/hot-100-news-billboard-and-nielsen-add-youtube-video-streaming-to-platforms)). It would be interesting to see the contribution of trending YouTube music videos (that correlate to the songs) to the Billboard charting songs.\n",
"\n",
"**Note**: the YouTube dataset only contains data from December 1, 2017 to May 31, 2018. I will be using a subset of the Billboard data to try and find correlations with this dataset.\n",
"\n",
"#### Step 1: Data Preparations"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# load the youtube data\n",
"yt_data = pd.read_csv('../raw_data/yt_us_videos.csv')"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" video_id | \n",
" trending_date | \n",
" title | \n",
" channel_title | \n",
" category_id | \n",
" publish_time | \n",
" tags | \n",
" views | \n",
" likes | \n",
" dislikes | \n",
" comment_count | \n",
" thumbnail_link | \n",
" comments_disabled | \n",
" ratings_disabled | \n",
" video_error_or_removed | \n",
" description | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 2kyS6SvSYSE | \n",
" 17.14.11 | \n",
" WE WANT TO TALK ABOUT OUR MARRIAGE | \n",
" CaseyNeistat | \n",
" 22 | \n",
" 2017-11-13T17:13:01.000Z | \n",
" SHANtell martin | \n",
" 748374 | \n",
" 57527 | \n",
" 2966 | \n",
" 15954 | \n",
" https://i.ytimg.com/vi/2kyS6SvSYSE/default.jpg | \n",
" False | \n",
" False | \n",
" False | \n",
" SHANTELL'S CHANNEL - https://www.youtube.com/s... | \n",
"
\n",
" \n",
" 1 | \n",
" 1ZAPwfrtAFY | \n",
" 17.14.11 | \n",
" The Trump Presidency: Last Week Tonight with J... | \n",
" LastWeekTonight | \n",
" 24 | \n",
" 2017-11-13T07:30:00.000Z | \n",
" last week tonight trump presidency|\"last week ... | \n",
" 2418783 | \n",
" 97185 | \n",
" 6146 | \n",
" 12703 | \n",
" https://i.ytimg.com/vi/1ZAPwfrtAFY/default.jpg | \n",
" False | \n",
" False | \n",
" False | \n",
" One year after the presidential election, John... | \n",
"
\n",
" \n",
" 2 | \n",
" 5qpjK5DgCt4 | \n",
" 17.14.11 | \n",
" Racist Superman | Rudy Mancuso, King Bach & Le... | \n",
" Rudy Mancuso | \n",
" 23 | \n",
" 2017-11-12T19:05:24.000Z | \n",
" racist superman|\"rudy\"|\"mancuso\"|\"king\"|\"bach\"... | \n",
" 3191434 | \n",
" 146033 | \n",
" 5339 | \n",
" 8181 | \n",
" https://i.ytimg.com/vi/5qpjK5DgCt4/default.jpg | \n",
" False | \n",
" False | \n",
" False | \n",
" WATCH MY PREVIOUS VIDEO ▶ \\n\\nSUBSCRIBE ► http... | \n",
"
\n",
" \n",
" 3 | \n",
" puqaWrEC7tY | \n",
" 17.14.11 | \n",
" Nickelback Lyrics: Real or Fake? | \n",
" Good Mythical Morning | \n",
" 24 | \n",
" 2017-11-13T11:00:04.000Z | \n",
" rhett and link|\"gmm\"|\"good mythical morning\"|\"... | \n",
" 343168 | \n",
" 10172 | \n",
" 666 | \n",
" 2146 | \n",
" https://i.ytimg.com/vi/puqaWrEC7tY/default.jpg | \n",
" False | \n",
" False | \n",
" False | \n",
" Today we find out if Link is a Nickelback amat... | \n",
"
\n",
" \n",
" 4 | \n",
" d380meD0W0M | \n",
" 17.14.11 | \n",
" I Dare You: GOING BALD!? | \n",
" nigahiga | \n",
" 24 | \n",
" 2017-11-12T18:01:41.000Z | \n",
" ryan|\"higa\"|\"higatv\"|\"nigahiga\"|\"i dare you\"|\"... | \n",
" 2095731 | \n",
" 132235 | \n",
" 1989 | \n",
" 17518 | \n",
" https://i.ytimg.com/vi/d380meD0W0M/default.jpg | \n",
" False | \n",
" False | \n",
" False | \n",
" I know it's been a while since we did this sho... | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" video_id trending_date \\\n",
"0 2kyS6SvSYSE 17.14.11 \n",
"1 1ZAPwfrtAFY 17.14.11 \n",
"2 5qpjK5DgCt4 17.14.11 \n",
"3 puqaWrEC7tY 17.14.11 \n",
"4 d380meD0W0M 17.14.11 \n",
"\n",
" title channel_title \\\n",
"0 WE WANT TO TALK ABOUT OUR MARRIAGE CaseyNeistat \n",
"1 The Trump Presidency: Last Week Tonight with J... LastWeekTonight \n",
"2 Racist Superman | Rudy Mancuso, King Bach & Le... Rudy Mancuso \n",
"3 Nickelback Lyrics: Real or Fake? Good Mythical Morning \n",
"4 I Dare You: GOING BALD!? nigahiga \n",
"\n",
" category_id publish_time \\\n",
"0 22 2017-11-13T17:13:01.000Z \n",
"1 24 2017-11-13T07:30:00.000Z \n",
"2 23 2017-11-12T19:05:24.000Z \n",
"3 24 2017-11-13T11:00:04.000Z \n",
"4 24 2017-11-12T18:01:41.000Z \n",
"\n",
" tags views likes \\\n",
"0 SHANtell martin 748374 57527 \n",
"1 last week tonight trump presidency|\"last week ... 2418783 97185 \n",
"2 racist superman|\"rudy\"|\"mancuso\"|\"king\"|\"bach\"... 3191434 146033 \n",
"3 rhett and link|\"gmm\"|\"good mythical morning\"|\"... 343168 10172 \n",
"4 ryan|\"higa\"|\"higatv\"|\"nigahiga\"|\"i dare you\"|\"... 2095731 132235 \n",
"\n",
" dislikes comment_count thumbnail_link \\\n",
"0 2966 15954 https://i.ytimg.com/vi/2kyS6SvSYSE/default.jpg \n",
"1 6146 12703 https://i.ytimg.com/vi/1ZAPwfrtAFY/default.jpg \n",
"2 5339 8181 https://i.ytimg.com/vi/5qpjK5DgCt4/default.jpg \n",
"3 666 2146 https://i.ytimg.com/vi/puqaWrEC7tY/default.jpg \n",
"4 1989 17518 https://i.ytimg.com/vi/d380meD0W0M/default.jpg \n",
"\n",
" comments_disabled ratings_disabled video_error_or_removed \\\n",
"0 False False False \n",
"1 False False False \n",
"2 False False False \n",
"3 False False False \n",
"4 False False False \n",
"\n",
" description \n",
"0 SHANTELL'S CHANNEL - https://www.youtube.com/s... \n",
"1 One year after the presidential election, John... \n",
"2 WATCH MY PREVIOUS VIDEO ▶ \\n\\nSUBSCRIBE ► http... \n",
"3 Today we find out if Link is a Nickelback amat... \n",
"4 I know it's been a while since we did this sho... "
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"yt_data.head()"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# keep only the videos from official YouTube music accounts (VEVO)\n",
"# stackoverflow link: https://stackoverflow.com/questions/11350770/select-by-partial-string-from-a-pandas-dataframe\n",
"yt_data_vevo = yt_data[yt_data['channel_title'].str.contains(\"vevo\",case=False)]\n",
"yt_data_vevo.to_csv('tmp_data/yt_data_vevo.csv')"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read billboard cleaned data\n",
"bboard_data = pd.read_csv('tmp_data/cleaned_bboard_data.csv')\n",
"# isolate dates to between Dec. 1, 2017 and May 31, 2018\n",
"bboard_data['WeekID'] = pd.to_datetime(bboard_data['WeekID'])\n",
"mask = (bboard_data['WeekID'] > '2017-12-01') & (bboard_data['WeekID'] <= '2018-05-31')\n",
"bboard_data = bboard_data.loc[mask]\n",
"bboard_data.to_csv('tmp_data/bboard_data_yt.csv')"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# join yt with billboard data\n",
"yt_data_vevo = pd.read_csv('tmp_data/yt_data_vevo.csv')\n",
"# merge on str.contains\n",
"# stackoverflow link: https://stackoverflow.com/questions/54756025/how-to-merge-pandas-on-string-contains\n",
"rhs = (bboard_data.Song\n",
" .apply(lambda song: yt_data_vevo[yt_data_vevo.title.str.find(song).ge(0)]['title'])\n",
" .bfill(axis=1)\n",
" .iloc[:, 0])\n",
"tmp = pd.concat([bboard_data.Song, rhs], axis=1, ignore_index=True).rename(columns={0: 'Song', 1: 'Video Title'})\n",
"# merge again to include the Video Title\n",
"rhs = (tmp.Song\n",
" .apply(lambda song: yt_data_vevo[yt_data_vevo.title.str.find(song).ge(0)]['views'])\n",
" .bfill(axis=1)\n",
" .iloc[:, 0])\n",
"tmp = pd.concat([tmp, rhs], axis=1, ignore_index=True).rename(columns={0: 'Song', 1: 'Video Title', 2: 'Views'})\n",
"tmp.to_csv('tmp_data/song_views.csv')"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Extract peak position for each song\n",
"bboard_data = pd.read_csv('tmp_data/cleaned_bboard_data.csv')\n",
"bboard_data = bboard_data.sort_values(['Peak Position', 'Weeks on Chart'], ascending=[True, False]).drop_duplicates([\"Song\"],keep='first')\n",
"bboard_data['Performer'] = bboard_data.Performer.map(str) + \" (\" + bboard_data.month.map(str) +\"-\" + bboard_data.year.map(str) + \")\"\n",
"bboard_data.to_csv('tmp_data/bboard_song_peak.csv')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read bboard_song_peak data\n",
"bboard_song_peak = pd.read_csv('tmp_data/bboard_song_peak.csv')\n",
"song_view = pd.read_csv('tmp_data/song_views.csv')\n",
"# merge bboard_song_peak with song_view to combine views, youtube title with the rest of bboard data\n",
"bboard_data = pd.merge(bboard_song_peak, song_view, how='left', left_on='Song', right_on='Song')\n",
"bboard_data = bboard_data.dropna()\n",
"# stackoverflow link: https://stackoverflow.com/questions/29370057/select-dataframe-rows-between-two-dates\n",
"bboard_data = bboard_data.loc[(bboard_data['year'] == 2018) | (bboard_data['year'] == 2017)]\n",
"bboard_data = bboard_data.drop_duplicates([\"Song\"],keep='last')\n",
"# divide by a million for ease of visualization later\n",
"bboard_data['Views'] = bboard_data['Views']/1000000\n",
"bboard_data['Views'] = bboard_data['Views'].round(2)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# sort on both year and month, select relevant columns, save to csv\n",
"bboard_data = bboard_data.sort_values(['year', 'month'], ascending=[True, True])\n",
"bboard_data = bboard_data[['Song','Performer', 'Peak Position', 'Weeks on Chart', 'Views', 'Video Title', 'year', 'month']]\n",
"bboard_data.columns = ['Song', 'Performer', 'Peak Position', 'Weeks on Chart', 'Views', 'Video Title', 'Year', 'Month']\n",
"bboard_data.to_csv('tmp_data/bboard_song_views.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 2: Data Visualization\n",
"\n",
"I will be preparing a marker chart that represents 3 dimensions of data: x-axis will show the songs, y-axis will show the peak position of the song, and the data point itself will be a marker with area measuring the corresponding YouTube music video views of the song."
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# read bboard_song_view dataframe\n",
"bboard_song_view = pd.read_csv('tmp_data/bboard_song_views.csv')"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hovertemplate": "%{x}
%{text}
Peak Position: %{y}
YouTube Views: %{marker.size}",
"marker": {
"cmax": 35,
"cmin": 0,
"color": [
5.05,
0.5,
0.51,
0.76,
0.21,
1.45,
0.13,
0.78,
14.09,
0.33,
0.03,
2.39,
5.05,
5.05,
4.51,
1.55,
2.96,
6.3,
2.48,
0.4,
0.49,
1.77,
0.95,
0.15,
4.87,
1.69,
3.07,
4.01,
0.34,
1.03,
5.48,
5.29,
1.06,
7.83,
0.43,
0.02,
31.65,
2.82,
1.92,
24.42,
15.87,
0.24,
14.82,
7.01
],
"colorbar": {
"title": {
"text": "YouTube Views (in millions)"
}
},
"colorscale": [
[
0,
"rgb(103,0,31)"
],
[
0.1,
"rgb(178,24,43)"
],
[
0.2,
"rgb(214,96,77)"
],
[
0.3,
"rgb(244,165,130)"
],
[
0.4,
"rgb(253,219,199)"
],
[
0.5,
"rgb(247,247,247)"
],
[
0.6,
"rgb(209,229,240)"
],
[
0.7,
"rgb(146,197,222)"
],
[
0.8,
"rgb(67,147,195)"
],
[
0.9,
"rgb(33,102,172)"
],
[
1,
"rgb(5,48,97)"
]
],
"line": {
"color": "DarkSlateGrey",
"width": 2
},
"size": [
5.05,
0.5,
0.51,
0.76,
0.21,
1.45,
0.13,
0.78,
14.09,
0.33,
0.03,
2.39,
5.05,
5.05,
4.51,
1.55,
2.96,
6.3,
2.48,
0.4,
0.49,
1.77,
0.95,
0.15,
4.87,
1.69,
3.07,
4.01,
0.34,
1.03,
5.48,
5.29,
1.06,
7.83,
0.43,
0.02,
31.65,
2.82,
1.92,
24.42,
15.87,
0.24,
14.82,
7.01
],
"sizeref": 0.46875
},
"mode": "markers",
"text": [
"21 Savage & Metro Boomin Featuring Future (2-2017)",
"Shawn Mendes (12-2017)",
"SZA (1-2018)",
"Maroon 5 Featuring SZA (2-2018)",
"Justin Timberlake (2-2018)",
"The Chainsmokers (2-2018)",
"Demi Lovato (3-2018)",
"Khalid (3-2018)",
"Taylor Swift Featuring Ed Sheeran & Future (3-2018)",
"Eminem Featuring Ed Sheeran (3-2018)",
"Russell Dickerson (3-2018)",
"Liam Payne & Rita Ora (3-2018)",
"Plies (3-2018)",
"G-Eazy Featuring A$AP Rocky & Cardi B (4-2018)",
"Migos, Nicki Minaj & Cardi B (4-2018)",
"G-Eazy & Halsey (4-2018)",
"Selena Gomez X Marshmello (4-2018)",
"Demi Lovato (4-2018)",
"P!nk (4-2018)",
"Imagine Dragons (5-2018)",
"Migos (5-2018)",
"NF (5-2018)",
"Carrie Underwood (5-2018)",
"Tank (5-2018)",
"Bruno Mars & Cardi B (6-2018)",
"Kendrick Lamar & SZA (6-2018)",
"The Weeknd & Kendrick Lamar (6-2018)",
"Jay Rock, Kendrick Lamar, Future & James Blake (6-2018)",
"Jason Aldean (6-2018)",
"Meghan Trainor (6-2018)",
"Camila Cabello Featuring Young Thug (7-2018)",
"Nicki Minaj (7-2018)",
"Jhene Aiko Featuring Swae Lee Or Rae Sremmurd (7-2018)",
"The Weeknd (8-2018)",
"Imagine Dragons (8-2018)",
"Luke Combs (8-2018)",
"Childish Gambino (9-2018)",
"Shawn Mendes (9-2018)",
"Calvin Harris & Dua Lipa (9-2018)",
"Drake (10-2018)",
"Ariana Grande (11-2018)",
"Zedd, Maren Morris & Grey (11-2018)",
"Taylor Swift (11-2018)",
"Selena Gomez (11-2018)"
],
"type": "scatter",
"x": [
"X",
"There's Nothing Holdin' Me Back",
"The Weekend",
"What Lovers Do",
"Filthy",
"Sick Boy",
"Sorry Not Sorry",
"Young Dumb & Broke",
"End Game",
"River",
"Yours",
"For You (Fifty Shades Freed)",
"Rock",
"No Limit",
"MotorSport",
"Him & I",
"Wolves",
"Tell Me You Love Me",
"Beautiful Trauma",
"Thunder",
"Stir Fry",
"Let You Down",
"Cry Pretty",
"When We",
"Finesse",
"All The Stars",
"Pray For Me",
"King's Dead",
"You Make It Easy",
"No Excuses",
"Havana",
"Chun-Li",
"Sativa",
"Call Out My Name",
"Whatever It Takes",
"One Number Away",
"This Is America",
"In My Blood",
"One Kiss",
"Nice For What",
"No Tears Left To Cry",
"The Middle",
"Delicate",
"Back To You"
],
"y": [
36,
6,
33,
9,
9,
65,
6,
18,
18,
32,
49,
76,
95,
4,
6,
14,
20,
53,
78,
4,
8,
12,
48,
78,
3,
7,
7,
21,
28,
46,
1,
10,
74,
4,
12,
34,
1,
11,
26,
1,
3,
5,
12,
18
]
}
],
"layout": {
"autosize": false,
"height": 700,
"margin": {
"b": 100,
"l": 50,
"pad": 4,
"r": 50,
"t": 100
},
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Top 100 Billboard #1 Songs in terms of Peak Position and YouTube Views 2017-2018",
"x": 0.5,
"xanchor": "center",
"y": 0.9,
"yanchor": "top"
},
"width": 1000,
"xaxis": {
"tickangle": 45,
"title": {
"text": "Song"
}
},
"yaxis": {
"title": {
"text": "Peak Position"
}
}
}
},
"text/html": [
"\n",
" \n",
" \n",
"
\n",
" \n",
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# create bubble chart\n",
"# stackoverflow link: https://plot.ly/python/bubble-charts/\n",
"# plotly colorscale: https://plot.ly/python/v3/matplotlib-colorscales/\n",
"bboard_song_view = pd.read_csv('tmp_data/bboard_song_views.csv')\n",
"fig = go.Figure()\n",
"\n",
"fig.add_trace(go.Scatter(\n",
" x=bboard_song_view['Song'],\n",
" y=bboard_song_view['Peak Position'],\n",
" mode='markers',\n",
" marker=dict(\n",
" line=dict(width=2, color='DarkSlateGrey'),\n",
" size=6,\n",
" cmax=35,\n",
" cmin=0,\n",
" color=bboard_song_view['Views'],\n",
" colorbar=dict(\n",
" title=\"YouTube Views (in millions)\"\n",
" ),\n",
" colorscale=\"RdBu\",\n",
" sizeref=2.*15/(8.**2)\n",
" ),\n",
" marker_size=bboard_song_view['Views'],\n",
" text=bboard_song_view['Performer'],\n",
" hovertemplate = \"%{x}
%{text}
Peak Position: %{y}
YouTube Views: %{marker.size}\",\n",
"))\n",
"\n",
"fig.update_layout(\n",
" title={\n",
" 'text': \"Top 100 Billboard #1 Songs in terms of Peak Position and YouTube Views 2017-2018\",\n",
" 'y':0.9,\n",
" 'x':0.5,\n",
" 'xanchor': 'center',\n",
" 'yanchor': 'top'},\n",
" autosize=False,\n",
" width=1000,\n",
" height=700,\n",
" margin=go.layout.Margin(\n",
" l=50,\n",
" r=50,\n",
" b=100,\n",
" t=100,\n",
" pad=4\n",
" ))\n",
"fig.update_xaxes(title_text='Song')\n",
"fig.update_xaxes(tickangle=45)\n",
"fig.update_yaxes(title_text='Peak Position')\n",
"\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Step 3: Findings - Data Analysis\n",
"\n",
"The complicated join between the YouTube dataset and Billboard resulted in only a few matching songs (57 in total) between 2017 and 2018, but it is clear that there are some relationships between a YouTube trending video with millions (or even billions) of views and the song's performance on the Billboard charts. \n",
"\n",
"Take 'This is America', by Childish Gambino, for example. The song has the most views on YouTube in this dataset, 32.65 million to be exact at the time of dataset publication (as of Nov. 2019: 621 million views), and it peaked at no. 1 on Billboard. 'Havana', by Camila Cabello, on the other hand, only has 5.48 million views at time of dataset publication, but also peaked at no. 1 (the video as of Nov. 2019, has 1.6 billion views).\n",
"\n",
"Next, we'll extract the top 10 songs. It's interesting to note that all 10 songs are from 2018."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Unnamed: 0 | \n",
" Song | \n",
" Performer | \n",
" Peak Position | \n",
" Weeks on Chart | \n",
" Views | \n",
" Video Title | \n",
" Year | \n",
" Month | \n",
"
\n",
" \n",
" \n",
" \n",
" 36 | \n",
" 1000 | \n",
" This Is America | \n",
" Childish Gambino (9-2018) | \n",
" 1 | \n",
" 17 | \n",
" 31.65 | \n",
" Childish Gambino - This Is America (Official V... | \n",
" 2018 | \n",
" 9 | \n",
"
\n",
" \n",
" 39 | \n",
" 438 | \n",
" Nice For What | \n",
" Drake (10-2018) | \n",
" 1 | \n",
" 25 | \n",
" 24.42 | \n",
" Drake - Nice For What | \n",
" 2018 | \n",
" 10 | \n",
"
\n",
" \n",
" 30 | \n",
" 121 | \n",
" Havana | \n",
" Camila Cabello Featuring Young Thug (7-2018) | \n",
" 1 | \n",
" 45 | \n",
" 5.48 | \n",
" Camila Cabello - Havana (Vertical Video) ft. Y... | \n",
" 2018 | \n",
" 7 | \n",
"
\n",
" \n",
" 40 | \n",
" 1875 | \n",
" No Tears Left To Cry | \n",
" Ariana Grande (11-2018) | \n",
" 3 | \n",
" 27 | \n",
" 15.87 | \n",
" Ariana Grande - No Tears Left To Cry | \n",
" 2018 | \n",
" 11 | \n",
"
\n",
" \n",
" 24 | \n",
" 1969 | \n",
" Finesse | \n",
" Bruno Mars & Cardi B (6-2018) | \n",
" 3 | \n",
" 23 | \n",
" 4.87 | \n",
" Bruno Mars and Cardi B - Finesse (LIVE From Th... | \n",
" 2018 | \n",
" 6 | \n",
"
\n",
" \n",
" 33 | \n",
" 2687 | \n",
" Call Out My Name | \n",
" The Weeknd (8-2018) | \n",
" 4 | \n",
" 18 | \n",
" 7.83 | \n",
" The Weeknd - Call Out My Name (Official Video) | \n",
" 2018 | \n",
" 8 | \n",
"
\n",
" \n",
" 13 | \n",
" 2462 | \n",
" No Limit | \n",
" G-Eazy Featuring A$AP Rocky & Cardi B (4-2018) | \n",
" 4 | \n",
" 28 | \n",
" 5.05 | \n",
" G-Eazy - No Limit REMIX ft. A$AP Rocky, Cardi ... | \n",
" 2018 | \n",
" 4 | \n",
"
\n",
" \n",
" 19 | \n",
" 2368 | \n",
" Thunder | \n",
" Imagine Dragons (5-2018) | \n",
" 4 | \n",
" 51 | \n",
" 0.40 | \n",
" Imagine Dragons - Thunder (Live On The Ellen D... | \n",
" 2018 | \n",
" 5 | \n",
"
\n",
" \n",
" 41 | \n",
" 2902 | \n",
" The Middle | \n",
" Zedd, Maren Morris & Grey (11-2018) | \n",
" 5 | \n",
" 40 | \n",
" 0.24 | \n",
" dodie - In The Middle | \n",
" 2018 | \n",
" 11 | \n",
"
\n",
" \n",
" 14 | \n",
" 3536 | \n",
" MotorSport | \n",
" Migos, Nicki Minaj & Cardi B (4-2018) | \n",
" 6 | \n",
" 21 | \n",
" 4.51 | \n",
" Migos, Nicki Minaj, Cardi B - MotorSport | \n",
" 2018 | \n",
" 4 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Unnamed: 0 Song \\\n",
"36 1000 This Is America \n",
"39 438 Nice For What \n",
"30 121 Havana \n",
"40 1875 No Tears Left To Cry \n",
"24 1969 Finesse \n",
"33 2687 Call Out My Name \n",
"13 2462 No Limit \n",
"19 2368 Thunder \n",
"41 2902 The Middle \n",
"14 3536 MotorSport \n",
"\n",
" Performer Peak Position \\\n",
"36 Childish Gambino (9-2018) 1 \n",
"39 Drake (10-2018) 1 \n",
"30 Camila Cabello Featuring Young Thug (7-2018) 1 \n",
"40 Ariana Grande (11-2018) 3 \n",
"24 Bruno Mars & Cardi B (6-2018) 3 \n",
"33 The Weeknd (8-2018) 4 \n",
"13 G-Eazy Featuring A$AP Rocky & Cardi B (4-2018) 4 \n",
"19 Imagine Dragons (5-2018) 4 \n",
"41 Zedd, Maren Morris & Grey (11-2018) 5 \n",
"14 Migos, Nicki Minaj & Cardi B (4-2018) 6 \n",
"\n",
" Weeks on Chart Views Video Title \\\n",
"36 17 31.65 Childish Gambino - This Is America (Official V... \n",
"39 25 24.42 Drake - Nice For What \n",
"30 45 5.48 Camila Cabello - Havana (Vertical Video) ft. Y... \n",
"40 27 15.87 Ariana Grande - No Tears Left To Cry \n",
"24 23 4.87 Bruno Mars and Cardi B - Finesse (LIVE From Th... \n",
"33 18 7.83 The Weeknd - Call Out My Name (Official Video) \n",
"13 28 5.05 G-Eazy - No Limit REMIX ft. A$AP Rocky, Cardi ... \n",
"19 51 0.40 Imagine Dragons - Thunder (Live On The Ellen D... \n",
"41 40 0.24 dodie - In The Middle \n",
"14 21 4.51 Migos, Nicki Minaj, Cardi B - MotorSport \n",
"\n",
" Year Month \n",
"36 2018 9 \n",
"39 2018 10 \n",
"30 2018 7 \n",
"40 2018 11 \n",
"24 2018 6 \n",
"33 2018 8 \n",
"13 2018 4 \n",
"19 2018 5 \n",
"41 2018 11 \n",
"14 2018 4 "
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# extract the top 10 songs by popularity first, then relevance\n",
"bboard_song_view.sort_values(['Peak Position', 'Views'], ascending=[True, False]).head(10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Data Limitations\n",
"\n",
"This study has generated some valuable insights about the many factors that shape a song's performance on the Billboard Top 100 Charts. However, there are still some limitations of this study, as well as confounding factors, that should be addressed. Please see below for the main assumptions of the study:\n",
"\n",
"#### Song Representation\n",
"\n",
"This study only looked at Billboard Top 100 Charts for US songs. It may very well be the case that a non-US song also performed well on the Billboard non-US Charts. In addition, due to the limitations of visualization, I kept only the top 100 songs with most number 1 week positions on the Billboard charts. If I included the rest of the songs, then there may be opportunities to uncover more patterns.\n",
"\n",
"#### Assumption about Popularity\n",
"\n",
"I create a rudimentary definition of popularity, based on the data columns I had. However, count of weeks the song is #1 dividedd by total of weeks the song spent on Billboard is not a comprehensive definition of popularity. There are many other factors that contribute to a song's popularity, and from a human-centered perspective, not everyone has the same definition of what makes a song popular. It is important to put this in context as we try to understand the visualizations I built.\n",
"\n",
"#### Billboard and Streaming Platforms\n",
"\n",
"In 2013,Billboard began accounting for song performance on streaming platforms as an additional factor in their charting algorithm. While we do not know what their formula is for calculating the ranking, we do know that a song's corresponding YouTube music video is already contributing to that song's performance after 2013. This confounding factor, when taken into account, makes the results from the third visualization intuitive to understand.\n",
"\n",
"### Implication & Future Work\n",
"\n",
"The results of this study highlights the tight relationships around a song's popularity, relevance, #1 streak, velocity, and corresponding YouTube music video virality. From the analysis, it is clear that a song tends to reach the Billboard top charts when it has a viral hit on YouTube with millions of views, but as we've seen in the limitations, this could be due to the confounding factor that YouTube is already accounted for in the Billboard chart formula.\n",
"\n",
"Similar to my method of combining the Billboard dataset with another dataset, there is great potential in adding more contextual datasets to the 4 dimensions of data I extracted (popularity, relevance, #1 streak, and velocity) for further insights. One example would be to analyze the song lyrics in addition to their performance on the charts; another is to extract song genres and artist category. "
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"### Conclusion & Reflection\n",
"\n",
"In both popularity & relevance as well as velocity & #1 streak, 2010s music only took 4 out of the top 10. This indicates that there are still many songs from the past (mostly 1980s-2000s) that have maintained their popularity, relevance, velocity, and #1 streak. While YouTube music video views indeed correlate with songs peaking near the top 10 on Billboard, this is already a confounding factor due to the fact that YouTube streaming data has been incorporated into Billboard Top 100 calculations since 2013.\n",
"\n",
"From a human-centered data science perspective, it was important for me to construct visualizations that not only helps me answer my initial research questions, but also provide the interactivity that allows viewers to explore & understand the data on their own.\n",
"\n",
"To a music enthusiast like myself, the results are comforting; in every decade, there are songs that defy their generations and continue to be appreciated by us; whether we heard the song in person during a concert in the 1980s, or listened on Spotify during the commute home in 2019, we continue to appreciate the music. Furthermore, the results show the importance of appreciating music from the past, because the music we love now can _become_ the past in a few decades.\n",
"\n",
"Lastly, please enjoy the Spotify playlist I compiled as part of my analysis!\n",
"\n",
"* Q1 Spotify Playlist: https://tinyurl.com/kfrankc-512-pl1 \n",
"* Q2 Spotify Playlist: https://tinyurl.com/kfrankc-512-pl2 \n",
"* Q3 Spotify Playlist: https://tinyurl.com/kfrankc-512-pl3 "
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"### Reference\n",
"\n",
"[1] https://www.wikiwand.com/en/Billboard_charts\n",
"\n",
"[2] https://www.grammy.com/grammys/news/what-music-goes-viral-tiktok\n",
"\n",
"[3] https://www.billboard.com/charts/digital-song-sales\n",
"\n",
"[4] https://www.billboard.com/chart-beat\n",
"\n",
"[5] https://towardsdatascience.com/billboard-hot-100-analytics-using-data-to-understand-the-shift-in-popular-music-in-the-last-60-ac3919d39b49"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}