Pythonでレーダーチャートを作成

コーンフレークといえばレーダーチャートを思い浮かべる人多いと思います。
特徴を比較するのにとても便利ですよね。

エクセルではサクッと描けたりしますし、アプリもたくさん出ています。

データ分析でPythonを使っていたらそのまま描いてしまいたいところですが、
Pythonで簡単にレーダーチャートが描けるPackageは無さそうです。。

勉強がてら作成してみましたのでメモ書きとして共有します。

今回はケロッグ コーンフレークのレーダーチャートを再現することに挑戦しました。
結果はこんな感じです。では、描いてみましょう!
    目次
  • Matplotlibで極座標グラフを描く
    • 必用Packageの用意
    • データの作成
    • レーダーチャート作成の準備
    • レーダーチャートの作図

Matplotlibで極座標グラフを描く

Matplotlibを使って描いていくわけなんですが、極座標グラフを描くことになります。
xyグラフのxが角度になったイメージですね。

必用Packageの用意

先に今回使うPackageを入れておきます。
日本語を使うのでjapanize_matplotlibも入れておきます。
Google Collaboratoryを使っていますがjapanize_matplotlibはインストールが必要です。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

pip install japanize_matplotlib

import japanize_matplotlib

データの作成

まずはデータを作りましょう。
data = pd.DataFrame({
    "カルシウム":[1.5,0.5],
    "鉄":[1.8,0.9],
    "ビタミンA":[1.5,0.8],
    "ビタミンB1":[1.2,0.4],
    "ビタミンB2":[2.1,0.7],
    "ナイアシン":[1,0.3],
    "ビタミンC":[1.5,0.7],
    "ビタミンD":[2,0.8]
})
data.index=["コーンフレーク","パン"]

data

レーダーチャート作成の準備

必要なものは
  • 角度(ラベルの数:360°を均等割りする)
  • ラベル
  • になります。
まずは角度から
# cnum : ラベルの数
cnum = len(data.columns)

# angles : 角度
angles = np.linspace(0,2*np.pi, cnum +1)
Numpyのpiとlinspaceを使って360°をラベルの数で均等割りしちゃいましょう。(隙間はラベルの数+1ですよね。)

次に値です。
# cvalues : コーンフレークの値
# pvaules : パンの値
cvalues = np.concatenate((data.loc["コーンフレーク"],[data.loc["コーンフレーク"][0]]))
pvalues = np.concatenate((data.loc["パン"],[data.loc["パン"][0]]))
レーダーチャートを閉じるために各値は最後に先頭の値をもう一度付け足しておきます。

最後にラベルです。
# labels : ラベル名
labels = data.columns

レーダーチャートの作図

# 作図
fig = plt.figure() #グラフの箱準備
ax = fig.add_subplot(111, polar = True) # 極座標系を作る

# 見映えを修正
# 北を視点にする
ax.set_theta_zero_location("N")
# 時計回りにする
ax.set_theta_direction(-1)

# ラベルの書き込みとメモリの最大値設定
ax.set_thetagrids(angles[:-1] * 180 / np.pi, labels)
ax.set_rlim(0,3)

# コーンフレーク部分
ax.plot(angles, cvalues,"o-")
ax.fill(angles, cvalues, alpha = 0.25)

# パン部分
ax.plot(angles, pvalues,"o-")
ax.fill(angles, pvalues, alpha = 0.25)
111というのは1行1列の1番目に配置するということになります。
横並びにするときはここを指定しながら並べればいいですね。
極座標なのでpolarをTrueにしましょう。

見映えを整えるために北(上)を始点にして、時計回りを指定しています。
ラベルは一周する必要ないのでangleから一つ引いておきましょう。
最後にプロットして薄く塗りつぶしました。

うまく再現できていますね。