League of Legendsのチャンプ間の分析

pythonのライブラリnetworkxの勉強がてらにLeague of Legends(以後LoL)におけるチャンピオン間のネットワークを作った.
LoLとは世界的に人気のオンラインゲームであり,全10人のプレイヤーが5人,5人に分かれて戦い合う.
下のようなマップで相手の陣地の一番奥にあるオブジェクトを最初に壊したチームが勝利である.
f:id:umashika5555:20170822042549j:plain
下の動画はLoLのプロゲームで私が最も好きな試合である.
www.youtube.com

LoLでは始め, レーン戦と呼ばれるtop,midと呼ばれる2つのレーンで1on1を行う.
またbotというレーンでは火力が高いが体力が低いadcという役職のプレイヤーと火力は低いが回復やシールド能力のあるsupという役職が2on2で戦う.
jungleというレーンは中間モンスターと呼ばれる,相手プレイヤーとは直接関係のないモンスターを狩り経験値を高めつつ,味方のレーンを補助しにいったりする.
このとき,レーン戦ではチャンピオンによって対面が得意, 不得意がある.
あるチャンピオンに対して, そのチャンピオンに有利なチャンピオンをカウンターチャンプという.
例えばAnnieというチャンピオンはmidレーンにおいて火力は高いのだが, 射程はかなり短い. したがって射程の長いBrandやOriannna,Luxといったチャンプに弱い. 逆に射程の短いFizzやAkaliといったチャンプに対しては非常に有利である.
カウンターチャンプの概念はかなり重要でプロの試合でもチャンピオンピックの時点で有利不利が決まらないように工夫されている.
__________________________________________________

まずはJSONファイルの取得からする必要がある.
LoL Counter - Champions
今回はこのサイトからスクレイピングした.
(スクレイピングのやり方についてはいつか記載)
JSONファイルはここにおいてある.
champion1.json - Google ドライブ


赤線が不得意チャンプ, 青線が得意チャンプ, 緑線が味方で相性の良いチャンプ

import json
import matplotlib.pyplot as plt
import networkx as nx

def get_champion_relations_dict():
    """JSONファイルを取得
    """
    with open("champion.json","r") as f:
        return json.load(f)

def add_edges(Graph,champion_name,tmp_list,edge_color):
    """チャンピオンに対してtmp_listのチャンピオンに対するエッジを追加する
    """
    Graph.add_edges_from([(champion_name,champion) for champion in tmp_list],color=edge_color) 

if __name__ == "__main__":
    #有向グラフを宣言
    Graph = nx.DiGraph()

    #チャンピオンのJSONを取得
    champion_relations_dict = get_champion_relations_dict()
        
    #ノードを追加する
    Graph.add_nodes_from(list(champion_relations_dict.keys()))
    
    #カウンターチャンピオンに有向エッジを追加
    relations_dict = {"weak":"r","strong":"b","goes_well":"g"}
    for champion_name in champion_relations_dict.keys():#あるチャンピオンに対して
        for relation,color in relations_dict.items():#ある関係に対して
            opponent_list = champion_relations_dict[champion_name][relation][:3]
            add_edges(Graph,champion_name,opponent_list,color)
        
    
    #グラフの描画
    edges = Graph.edges()
    colors = [Graph[u][v]["color"] for u,v in edges]
    plt.figure(figsize=(50,50))
    pos = nx.spring_layout(Graph)
    labels=nx.draw_networkx_labels(Graph,pos=nx.spring_layout(Graph))
    nx.draw_networkx(Graph,pos,edge_color=colors,node_color="w",alpha=0.5,edge_labels=labels,font_size=9)
    plt.axis("off")
    plt.savefig("default.png")
    plt.show()

結果はいろいろ調整して以下のようになった.
f:id:umashika5555:20170822044629p:plain
f:id:umashika5555:20170822044635p:plain
f:id:umashika5555:20170822052216p:plain
f:id:umashika5555:20170822044641p:plain
正直, かなり見づらいしノードが多いため目的のチャンプを探すのに時間がかかる.
またノードの◯が表示されない場所があるのはライブラリの関係なのだろうか?
あと, グラフのノードの散乱をpos = nx.spring_layout(Graph,k=0.7)のように反発係数でやる以外に方法はないのか?
凡例の表示をどうするか?などの問題を解決していけたらよい.
これらを直せたら直していきたい.


【参考にしたサイト】
本家
https://networkx.github.io/documentation/networkx-1.9/examples/drawing/labels_and_colors.html
https://networkx.github.io/documentation/networkx-1.10/reference/functions.html
stack overflow
https://stackoverflow.com/questions/25639169/networkx-change-color-width-according-to-edge-attributes-inconsistent-result
https://stackoverflow.com/questions/24873626/python-networkx-adding-color-for-a-particular-edge
https://stackoverflow.com/questions/22992009/legend-in-python-networkx
Qiita
http://qiita.com/hitsumabushi845/items/270d81c5c8017014df95
http://qiita.com/inoory/items/088f719f2fd9a2ea4ee5
http://qiita.com/hatchinee/items/a904c1f8d732a4686c9d
Python辞書について
http://www.yukun.info/blog/2008/06/python-dict2.html