Kevin's Data Analytics Blog

データサイエンティスト、AIエンジニアを目指す方に向けて情報発信していきます。

【Python/Pandas】Webページ上のデータを読み込んで、動く棒グラフを作成する方法|AKB48 シングル選抜回数

こんにちは。今回は、Web上に公開されているAKB48歴代シングルにおける選抜メンバーの一覧表を読み込んで、メンバーごとの選抜回数の推移を集計し、動く棒グラフ(Bar Chart Race)で可視化したいと思います。

f:id:dskevin:20210626161830p:plain:h320
AKB48のディスコグラフィー/選抜メンバーの一覧 - エケペディア

youtu.be

事前準備

今回も、ツールはPythonを使用します。Pythonのセットアップ方法は過去の記事を参照ください。
データサイエンティストを目指す方向け Pythonセットアップ方法(Windows版) - Kevin's Data Analytics Blog

また、Pythonを使って動く棒グラフを作成するためには、PCにいくつかのソフトウェアをインストールする必要があります。こちらも手順については、過去の記事でまとめていますので、併せてご参照ください。
Pythonで動く棒グラフを作成する方法|Bar Chart Race - Kevin's Data Analytics Blog

Webページ上のデータの読み込み

Pythonの実行環境を開いたら、まず、Pandasライブラリをインポートします。

import pandas as pd

Pandasライブラリが用意しているpd.io.html.read_html()という関数を使用すると、指定したURLから表形式のデータだけを抜き出してくれます。

target_url = 'https://48pedia.org/AKB48%E3%81%AE%E3%83%87%E3%82%A3%E3%82%B9%E3%82%B3%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%BC/%E9%81%B8%E6%8A%9C%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E3%81%AE%E4%B8%80%E8%A6%A7'
tables = pd.io.html.read_html(target_url)

実行すると、tablesという変数に、URL内の表データがリスト形式で保存されるので、1番目(リストの番号は0始まりなので0)を指定して、dfという変数に格納します。

df = tables[0]

変数名だけで実行すると、変数の中身をみることができます。

df

f:id:dskevin:20210626170646p:plain

データの読み込みが出来ました。

データの加工

動く棒グラフを書くためにデータを加工します。

不要な列の削除

del 関数を使用して、列を削除します。今回は、一番左の「所属」列と一番右の「選抜回数」列は使用しないので、それぞれ、列番号を指定して削除します。

del df[df.columns[61]]
del df[df.columns[0]]
不要な行の削除

「名前」もしくは「定員」から始まる行を削除します。

df = df[df[df.columns[0]]!='名前']
df = df[df[df.columns[0]]!='定員']
列名の加工

列名が3階層(発売年、枚数、曲名)になっているため、1階層にまとめます。また、元のサイトでは、曲名は縦書きですが、これを横書きにするために、記号文字を変換します。replace関数を使って、「|」→「ー」、「 `」→「、」とします。

df.columns = [df.columns[i][0]+'年\n'+df.columns[i][1]+'. '+df.columns[i][2] for i in range(len(df.columns))]
df.columns = [df.columns[i].replace('|','ー').replace(' `','、') for i in range(len(df.columns))]
データ値の変換

欠損値は選抜されなかったことを表すため「0」に、「●」と「★」は選抜されたことを表すため「1」に変換します。欠損値の置き換えは、fillna関数を使用します。

df = df.fillna(0).replace('●',1).replace('★',1)
行と列の入れ替え

元のデータは、左から右の順番で古いシングルから新しいシングルのデータが格納されています。動く棒グラフを作成するために、上から下に時系列が進むように行と列を入れ替えます。このような操作を行列の転置といい、データの変数に「.T」をつけて実行すると転置されます。また、転置前の行インデックスが転置後の列名になりますので、set_index関数を使用して、転置前に1列目のメンバーの名前をインデックスに指定します。

df = df.set_index(df.columns[0]).T

  
ここまでのデータ加工のイメージは以下のとおりです。
f:id:dskevin:20210627155113p:plain

累積和の計算

最後に、cumsum関数を使用して、列ごとに縦方向に累積和を計算します。これにより各データの値は、該当行のシングル曲の時点における、それまでの合計の選抜回数を表します。

f:id:dskevin:20210627160133p:plain

これで、動く棒グラフを作成するためのデータ準備ができました。

動く棒グラフの作成

加工後のデータを利用して、動く棒グラフを作成します。
 
今回はデータに日本語を含むので、japanize_matplotlibというPythonライブラリをインストールして、Pythonのグラフ描画機能を日本語データに対応させる必要があります。もし、まだインストールしていない場合は、コマンドプロンプトから以下のコマンドを実行します。

pip install japanize_matplotlib

 
Pythonの実行環境に戻って、ライブラリをインポートします。

import bar_chart_race as bcr
import japanize_matplotlib

bar_chart_race関数に、先ほど加工したデータ「df」を指定して、動く棒グラフを作成します。パラメータの値はお好みで調整ください。

bcr.bar_chart_race(
    df=df
    ,fixed_max=True
    ,title='AKB48 歴代メンバー シングル選抜回数 ランキング推移 2006.02-2021.06 '
    ,n_bars=27
    ,bar_size=.8
    ,period_label={'x': .975, 'y': .075, 'ha': 'right', 'va': 'center', 'size': 13}
    ,filter_column_colors=True
)

f:id:dskevin:20210627162927p:plain

グラフのカスタマイズ

スマホ表示用に動画を縦長にする

fig_kwargsというパラメタで動画サイズを指定します。スマホ用の動画は、横と縦の比率が9:16が適していますので、文字サイズとのバランスを考慮して、それぞれ1/2にして4.5:8とします。

bcr.bar_chart_race(
    df=df
    ,fixed_max=True
    ,title='AKB48 歴代メンバー シングル選抜回数 ランキング推移 2006.02-2021.06 '
    ,n_bars=27
    ,bar_size=.8
    ,period_label={'x': .975, 'y': .05, 'ha': 'right', 'va': 'center', 'size': 11}
    ,fig_kwargs={'figsize': (4.5, 8), 'dpi': 72}
    ,filter_column_colors=True
)

f:id:dskevin:20210627171556p:plain

棒の色を指定する

例として、メンバーの所属チームに応じて、棒の色を変えてみたいと思います。
まずは、前準備として、Excelファイルに各メンバーの所属チームをまとめます。複数所属している場合は、代表的なチームを選んでいます。なお、メンバーの並び順をウェブから取得したテーブルとExcelファイルで一致させる必要がある点にご注意ください。
f:id:dskevin:20210627164352p:plain:h320

pd.read_excel関数を使用して、こちらのExcelファイルを読み込みます。

member_team=pd.read_excel('../data/member_team.xlsx')

「color」という列を追加して、「team」列の値に応じて色を指定します。replace関数を使用して、'A'などのチーム名を'red'などの色の名称に変えていきます。

member_team['color']=member_team['team'].replace('A','red').replace('K','lime').replace('B','aqua').replace('SKE','orange').replace('NMB','gold').replace('HKT','dimgrey').replace(4,'skyblue')
# チーム不明のメンバーはwhiteで補完
member_team['color']=member_team['color'].fillna('white')
member_team

f:id:dskevin:20210627165435p:plain:h320

filter_column_colorsをFalseにして、colorsに先ほど作成したデータの「color」列の値を指定します。

bcr.bar_chart_race(
    df=df
    ,fixed_max=True
    ,title='AKB48 歴代メンバー シングル選抜回数 2006.2-2021.6  '
    ,n_bars=27
    ,bar_size=.8
    ,period_label={'x': .975, 'y': .05, 'ha': 'right', 'va': 'center', 'size': 11}
    ,fig_kwargs={'figsize': (4.5, 8), 'dpi': 72}
    ,filter_column_colors=False
    ,colors=member_team['color']
)

f:id:dskevin:20210627171845p:plain

まとめ

Webページからデータ取得、データ加工、動く棒グラフの作成、という一連のプロセスを全てPythonで実装できました。このように、様々な処理を実装できる事がPythonの大きな魅力の1つです。今回の記事が皆様のPython活用の参考になれば幸いです。

今回も、記事の内容を実演した様子を動画にしてアップしています。文章で分かりづらい点は、こちらの動画もあわせてご確認ください。
youtu.be

最後まで読んでいただき、ありがとうございました。