レーダーチャートはmatplotlibなどにはデフォルトがなく、自前実装が必要です。自分の用途に合わせ得て最低限データフレームとシリーズにそれぞれ対応した関数をまとめておきます
基本的な処理
- 表示の設定を行う
- ベースの表示を円形にする
- x軸(ここでは、可視化する変数数)を円上に均等に割り当てる
y軸(ここでは、上の軸の長さ)を設定する
データの可視化を行う
- 対象のデータのxとyの位置を指定し線でつなぐ
シリーズを渡す場合
indexがx軸の数(可視化軸)、値がy軸(位置)であるとします。
import matplotlib.pyplot as plt import pandas as pd def rader_chart(pd_series): # x軸の数と、配置のための角度を計算する vertex_num = [v for v in range(pd_series.size)] f = lambda x : x / len(vertex_num) * 2 * 3.14 angles = list(map(f,vertex_num)) #表示の設定を行う ax = plt.subplot(111,polar=True) plt.xticks(angles,pd_series.index) plt.ylim(0,pd_series.max()) #データの可視化を行う plot_data = list(pd_series.values) plot_data += plot_data[:1] angles += angles[:1] ax.plot(angles,plot_data) v = pd.Series([i * 10 for i in range(6)]) rader_chart(v) rader_chart(v[::-1])
二回実施ずれば重ねることも可能です。
ただし、このままだと、最大値が違う場合、うまく表示できません。 データフレーム版も検討します。
データフレームの場合
ピボットテーブルやgroupbyしたデータを渡すことをイメージします。 このときindexが線そのものの数、columnがx軸の数であることを想定します。
コードはほぼ同じです。
def rader_chart_from_df(pd_df): vertex_num = [v for v in range(pd_df.shape[1])] f = lambda x : x / len(vertex_num) * 2 * 3.14 angles = list(map(f,vertex_num)) ax = plt.subplot(111,polar=True) plt.xticks(angles,pd_df.columns) plt.ylim(0,pd_df.max().max()) #ループを回して、グループごとに可視化する angles += angles[:1] for col in pd_df.T.columns: plot_data = pd_df.T[col].to_list() plot_data += plot_data[:1] ax.plot(angles,plot_data,label=col) plt.legend()
import random df = pd.DataFrame( { 'ctg_a':[10,20,30,40,50], 'ctg_b':[random.random() * 100 for i in range(5)], 'ctg_c':[random.random() * 100 for i in range(5)], 'ctg_d':[random.random() * 100 for i in range(5)] } ,index = ['A','B','C','D','E'] ) rader_chart_from_df(df)
ファセットは今後考えるとします。