ネットワークグラフをつくるためのTableauとPython
Tableauでネットワークグラフを可視化しようとすると、座標データをどう用意するかが一番ネックになると思います。
現状、Tableau内でネットワークグラフを自動生成する機能は無さそうです。
ので、この辺の処理はPythonを噛ませると楽にできるので、ちゃんとできるか試行します。
networkxによる処理
そもそもnetworkxを使って完結しちゃえばいいじゃん、という話ではありますが、
TableauはじめBIプラットフォーム上で表現できれば色々使用用途が高いです。
まずはリファレンスに従い、乱数を固定しておいたほうが良さそうです。
import random random.seed(246) import numpy numpy.random.seed(4812)
pandas.DataFrame
で以下のようなサンプルデータを用意。
import pandas as pd edge_df = pd.DataFrame({ "source":["A","B","B","C","A","C","C","A","B","F","E","A","H"], "target":["B","C","D","D","E","E","F","G","G","G","H","I","I"], "weight":[0.6,0.1,0.2,0.9,0.8,0.7,0.5,0.3,0.8,0.1,0.7,0.4,0.8] })
networkx
を使用して、任意のアルゴリズムによるノードの座標を取得しておきます。
import networkx as nx G = nx.from_pandas_edgelist(edge_df,edge_attr=True) pos = nx.spring_layout(G)
この座標情報をテーブル化してTableauに読ませることになります。
なお、普通に描写するとこんな感じ。
edges = G.edges() weights = [G[u][v]['weight'] for u,v in edges] nx.draw(G, pos, edges=edges, width=weights, node_size=400, node_color="c",with_labels=True,font_weight="bold")
エッジのweight以外も属性をつけることが可能です。
その場合、上記の例ではinput_dfに別カラムをつけ、edge_attr=True
をしておけばOK。
これと同じネットワークグラフをTableauで描写するのが目的です。
pos
はdict型なので、テーブル化しておきます。
print(type(pos)) print(pos) >>> <class 'dict'> >>> {'A': array([ 0.05494571, -0.43277963]), 'B': array([0.38390294, 0.05184413]), 'C': array([-0.08115845, 0.52158239]), 'D': array([-0.08585107, 0.92455717]), 'E': array([-0.38630969, -0.13289213]), 'F': array([0.5411944 , 0.85869962]), 'G': array([ 0.75986786, -0.13710168]), 'H': array([-0.73922077, -0.65390988]), 'I': array([-0.44737093, -1. ])}
import pandas as pd node = [] x = [] y = [] for k,v in nodePos.items(): node.append(k) x.append(v[0]) y.append(v[1]) node_df=pd.DataFrame({ "item":node, "X":x, "Y":y })
作成したノードの座標情報データnode_df
と、
最初につくったエッジの情報データedge_df
をTableauへ送り込む用に加工します。
result_df_1 = pd.merge(edge_df,node_df,how="left",left_on="source",right_on="item") result_df_2 = pd.merge(edge_df,node_df,how="left",left_on="target",right_on="item") result_df = pd.concat([result_df_1, result_df_2]) result_df["edge_name"] = result_df["source"] + "_" + result_df["target"]
edge_df
を縦積みにして、source
,target
それぞれのX座標,Y座標をjoinします。
おまけにfrom-toを表すedge_name
をつけておきます。
よーし、準備OK!
result_df
をTableauに持っていくぞー。
Tableauによる表現
まずはX,Y座標によるscatter plotにして二重軸にします。
X,Y座標のメジャーを「合計」にしないように注意。
「平均」とか「最大」とかを選びましょう。
1つめの軸はディメンションのedge_name
を詳細にドラッグ(item
よりも上の階層)してマークの種類は「線」、
edgeの太さや色はweight
でお好きに加工。
edgeの完成です。
2つめの軸のマークは「点」、詳細はitem
だけでOKで、適当にラベルとか大きさを調整します。
これでnodeの完成。
あとは二重軸を同期して完成です~
無事、networkxと同じ描写ができましたね。
BIに載せることができると、表示範囲のフィルタリング等がしやすいので重宝しそうです。
データも最低限source, targetの情報さえあれば描写できちゃいますしね。