スポンサーリンク

【Spotify API】Pythonで関連アーティストのネットワーク図を描く

Python

Spotify APIを使ってPythonで関連アーティストのネットワーク図を描く方法を紹介します。

今回、描画してみたネットワーク図は下記になります。

ネットワークス図の上部はJ-Popの王道系アーティスト、左下はアイドル、右下にはロックバンドが分布しているようなネットワーク図を書くことができました。

自分の好きなアーティストに関連するアーティストを簡単に可視化することができます。まだ知らないアーティストを見つけることができたりしそうですね。

それではネットワーク図を描く方法を紹介します。

Rakuten

Spotify APIの準備

h2_0

まずはSpotify APIを使うための準備を行います。詳しくは「Spotify APIの準備をする」をご覧ください。

PythonでSpotify APIを使うためには必要になりますので準備しましょう。

Spotify Appの作成

下記のサイトからSpotify Appの作成を行います。Spotify Appの作成にはSpotifyのアカウント登録が必要となりますのでご準備ください。

PythonでSpotify APIを使用するためにClient IDClient Secretを取得します。

Spotipyのインストール

SpotipyはPythonでSpotify APIを扱うためのライブラリになります。Spotipyを使用することで音楽データやアーティスト情報を取得することが簡単にできます。

Python環境がなくてもGoogle Colaboratorを使えば、Pythonをブラウザ上で実行できます。Googleアカウントをお持ちであれば利用できるので、お試しください。

関連アーティストのネットワーク図を描く

それでは、Spotify APIを使ってPythonで関連アーティストのネットワーク図を描いてみます。

Spotify APPの設定

Spotify APPのアカウント認証を行います。下記コードのClient IDClient Secretを書き換えます。

# import modules
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

client_id = 'XXXXXXXXXXXXXXXX' # App作成時のClient ID
client_secret = 'XXXXXXXXXXXXXXXX' # App作成時のClient Secret
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

ネットワーク図を可視化

今回は関連アーティストの名前とSpotifyからpopularityという指標の大小によってノードの色を変えたいと思います。popularityの大きさによって「橙」→「赤」→「黄」→「緑」→「青」の順に設定します。

また、ノードから出ているエッジの数によってノードの大きさを変更します。関連のつながりが多いアーティストは円のサイズが大きくなります。

今回は「SPITZ」の関連アーティストをネットワーク図で可視化します。

SPITZの周りにメジャーな誰もが知るようなアーティストが表示され、人気度が高い赤色で出てきているのは「Mr.Children」「back number」「星野源」「乃木坂46」といった有名なアーティストでした。

コードの全体像は下記にまとめておきます。

class SpotifyInfo:
    
    def __init__(self):
        self.name = None
        self.popularity = None
        self.uri = None
        self.G = nx.Graph()
        self.vias = 1
        self.popularity_list = []
        
    def get_artist_uri(self, name):
        '''
        アーティスト名からuriを返す
        '''
        artist = spotify.search(q='artist:' + name, type='artist')['artists']['items'][0]
        self.name = artist['name']
        self.popularity = artist['popularity']
        self.uri = artist['uri']
        
        return self.uri
    
    def get_related_artist_info(self, uri):
        '''
        関係アーティストの情報をDataFrameで返す
        
        '''
        df = pd.DataFrame()
        for artist in spotify.artist_related_artists(uri)['artists']:

            tmp = pd.Series([], name=artist['name'])
            for key in ['popularity', 'uri']:
                tmp[key] = artist[key]

            df = pd.concat([df, pd.DataFrame(tmp).T])
            
        return df
            
    def add_nodes(self, df):
        
        if self.name not in self.G.nodes:
            self.G.add_node(self.name)
            self.popularity_list.append(self.popularity * self.vias)
        
        for name in df.index.tolist():
            if name not in self.G.nodes:
                self.G.add_node(name)
                self.popularity_list.append(df.loc[name, 'popularity'] * self.vias)
            
    def add_edges(self, target_name, df):
        for name in df.index.tolist():
            if (target_name, name) not in self.G.edges:
                self.G.add_edge(target_name, name)

    def _node_color(self, popularity):
        color_list = ['orangered', 'lightcoral', 'gold', 'lime', 'lightsteelblue', 'royalblue']
        
        if popularity >= 70:
            return color_list[0]
        elif popularity >= 60:
            return color_list[1]
        elif popularity >=50:
            return color_list[2]
        elif popularity >= 40:
            return color_list[3]
        elif popularity >= 30:
            return color_list[4]
        else:
            return color_list[5]
            
    def draw_related_map(self, name, level=2):
        uri = self.get_artist_uri(name)
        df = self.get_related_artist_info(uri)
        
        # add info to draw relation graph
        self.add_nodes(df)
        self.add_edges(self.name, df)
        
        
        for name in df.index.tolist():
            tmp_df = self.get_related_artist_info(df.loc[name, 'uri'])
            
            # add info to draw relation graph
            self.add_nodes(tmp_df)
            self.add_edges(name, tmp_df)

        plt.figure(figsize=[30, 30])
        pos = nx.spring_layout(self.G, seed=1, k=0.2)
        nx.draw_networkx_labels(self.G, pos, font_color='k', font_family='IPAexGothic')
        nx.draw_networkx_nodes(self.G, pos, alpha=0.7, node_shape='o', linewidths=1, 
                               node_size=[nx.degree_centrality(self.G)[i]*20000 for i in self.G.nodes],
                               node_color=list(map(self._node_color, self.popularity_list)))
        nx.draw_networkx_edges(self.G, pos, alpha=0.3)


spotifiinfo = SpotifyInfo()  # インスタンス化
spotifiinfo.draw_related_map('SPITZ')  # SPITZのネットワーク取得
plt.show()  # ネットワーク図を描画

一番最初に紹介したネットワーク図は同じインスタンスに対して再度関連アーティストの情報を上書きすることで描くことができます。

spotifiinfo = SpotifyInfo()  # インスタンス化
spotifiinfo.draw_related_map('SPITZ')  # SPITZのネットワーク取得
spotifiinfo.draw_related_map('Nogizaka46')  # Nogizaka46のネットワーク取得
spotifiinfo.draw_related_map('Hi-Standard')  # Hi-Standardのネットワーク取得
plt.show()

まとめ

h2_4

今回はSpotify APIを使ってPythonで関連アーティストからネットワーク図の描画を実践してみました。

Spotify APIはアーティスト情報だけでなく曲の分析などもできるみたいなので今度やってみようかなと思います。

コメント

タイトルとURLをコピーしました