First of all, register Your Application With Spotify. In order to access certain features of the Web API, we need to tell spotify that we're a legitimate app. To do this, go to https://developer.spotify.com/my-applications and create a new Application.
For the Redirect URI, add http://localhost/
From that page, copy your ClientId and your ClientSecret.
You need to set your Spotify API credentials. You can do this by setting environment variables like so:
Go to https://plot.ly/settings/api#/ and get api key.
os.environ['SPOTIPY_CLIENT_ID'] = 'your-spotify-client-id'
os.environ['SPOTIPY_CLIENT_SECRET'] = 'your-spotify-client-secret'
os.environ['SPOTIPY_REDIRECT_URI' ] = 'http://localhost/'
import numpy as np
import pandas as pd
from sklearn.preprocessing import minmax_scale
from sklearn.preprocessing import StandardScaler
import spotipy
import random
import os
import requests
import spotipy.util as util
from requests.auth import HTTPBasicAuth
import matplotlib.pyplot as plt
from matplotlib import font_manager
from math import pi
SPOTIPY_CLIENT_ID = os.environ.get('SPOTIPY_CLIENT_ID')
SPOTIPY_CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
SPOTIPY_REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')
# Get token
token = util.oauth2.SpotifyClientCredentials(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET)
cache_token = token.get_access_token()
spotify = spotipy.Spotify(cache_token)
origin_df = pd.read_csv("./spotify-id.csv")
origin_df = pd.DataFrame(origin_df)
origin_df
song_ids = list(origin_df['spotify_id'])
song_ids
all_track_popularity = []
for song_id in song_ids:
result = spotify.track(song_id)
all_track_popularity.append(result['popularity'])
popularity_df = pd.DataFrame({'popularity': list(all_track_popularity)})
popularity_df.columns = ['popularity']
popularity_df
pd.concat([origin_df.year, origin_df.title, popularity_df], axis=1, sort=False)
all_audio_features = []
for song_id in origin_df['spotify_id']:
result = spotify.audio_features([song_id])[0]
all_audio_features.append(result)
all_audio_features_df = pd.DataFrame(all_audio_features)
pd.concat([origin_df.year, origin_df.title, all_audio_features_df], axis=1, sort=False)
Audio Features Object - Spoity API
features_keys = ['loudness', 'acousticness', 'duration_ms', 'energy', 'speechiness', 'acousticness', 'liveness', 'danceability', 'valence', 'key', 'tempo']
# Get list of features and normalize values from 0 to 1
# In order to plot, normalize the key, loudness, tempo, and duration_ms values to be from 0 to 1.
def normalized(key, lst):
feature = [x[key] for x in lst]
if key in features_keys:
return list(minmax_scale(feature))
else:
return feature
audio_features_res = {}
for key in features_keys:
audio_features_res[key] = normalized(key, all_audio_features)
audio_features_df = pd.DataFrame(audio_features_res)
audio_features_df.rename(columns={'duration_ms':'duration'}, inplace=True)
audio_features_df
radar_chart_df = pd.concat([origin_df.year, origin_df.title, audio_features_df], axis=1, sort=False)
radar_chart_df
# Set font
FONT_NAME = "Hack Nerd Font"
plt.rcParams['font.family'] = FONT_NAME
plt.rcParams['axes.unicode_minus'] = False
df = radar_chart_df
SONG_YEARS = origin_df['year']
SONG_TITLES = origin_df['title']
# List all fonts available in matplotlib plus samples
# http://jonathansoma.com/lede/foundations-2018/matplotlib/list-all-fonts-available-in-matplotlib-plus-samples/
def make_spider(row, title, color):
# number of variable
categories=list(df)[2:]
N = len(categories)
# What will be the angle of each axis in the plot? (we divide the plot / number of variable)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
# Initialise the spider plot
ax = plt.subplot(10,3,row+1, polar=True)
# If you want the first axis to be on top:
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
# Draw one axe per variable + add labels labels yet
plt.xticks(angles[:-1], categories, color='grey', size=8)
ax.tick_params(axis='both', which='major', pad=15)
# Draw ylabels
ax.set_rlabel_position(0)
plt.yticks([0.0, 0.5, 1], ["0.0","0.5", "1"], color="grey", size=7)
plt.ylim(0,1)
# Set starting index
values=df.iloc[row].tolist()[2:]
values += values[:1]
ax.plot(angles, values, color=color, linewidth=2, linestyle='solid')
ax.fill(angles, values, color=color, alpha=0.4)
# Add a title
plt.title(title, size=11, color=color, y=1.2)
# initialize the figure
my_dpi=100
plt.figure(figsize=(1500/my_dpi, 4000/my_dpi), dpi=my_dpi)
plt.subplots_adjust(hspace = .8)
plt.suptitle(f'NDP SONGS - Spotify Audio Features Analysis', y=.95, fontsize=16, va='center')
# Create a color palette
my_palette = plt.cm.get_cmap("tab10")
# Loop to plot
for row in range(0, len(df.index)):
make_spider(row=row, title=f'({SONG_YEARS[row]}) {SONG_TITLES[row]}', color=my_palette(int(row/3)))
if not os.path.exists('image'):
os.makedirs('image')
plt.savefig(f'image/ndp-songs-spotify.png', dpi=300)
plt.show()
plt.close()