Hello Wor.log

IT系大学生4人による備忘録のようなもの

networkxでマルチグラフとか、綺麗なグラフを書く【python】

CPPXのXです。

グラフを扱ってる時、今どんな状態かなーって確認したい時、綺麗なグラフを見たいですよね。
networkxを使ってグラフを表示していきます。

ただ、デフォの赤丸のやつだと見にくいので、agraphを使って見やすくします。
マルチグラフも対応しています。

環境導入はここでは説明しません。
大量に記事が転がっているのと、詰まりポイントが無かったためです。

では目次です。

環境

  • python 3.5.3
  • networkx 1.11
  • pygraphviz 1.3.1

imports

import networkx as nx
from IPython.display import display_svg #  jupyterで表示するのであれば

概要

グラフの表示結果
こんなのを作成します

加工したグラフ
おまけで、加工もしていきます

早速やっていきます。

データ

上のシンプルなグラフの方を説明していきます。

nodes = [0, 1, 2, 3, 4]
edges = [
    (0, 1), (1, 2), (2, 3), (3, 4), (4, 0), #  0 ~ 4を輪っか状に
    (0, 0), (0, 0), #  自己ループ
    (1, 2), (1, 2), #  同じ経路複数
    (1, 3), (1, 4), (3, 1), (4, 1) #  双方向
    ]

ノードの定義は、まあよいです。

エッジですが、有向グラフなら(from, to)を適当に投げ込んで行けば繋がります。

グラフの表示

本題です。
準備は整ったので、グラフの表示をしていきます。

とりあえずソースコード載っけます。

g = nx.MultiDiGraph() #  グラフの種類

g.add_nodes_from(nodes) #  グラフにノード追加
g.add_edges_from(edges) #  グラフにエッジ追加

agraph = nx.nx_agraph.to_agraph(g)
agraph.node_attr["shape"] = "circle" #  表示方法変更
img = agraph.draw(prog="dot", format="svg")
display_svg(img, raw=True) #  jupyterで表示

nx.MultiDiGraph()のところでグラフの種類を決定できます。
nx.Graph()とかにすると、無向グラフにできたりとか。

add_nodes...とかしてる下、agraphとか書いてあるあたりから、よく紹介されているものと変わってきます。
nx.nx_agraph.to_agraph(g)で、pygraphvizのAGraphに変換します。

丸表示が好きだったので、agraph.node_attr["shape"] = "circle"でノードの表示を丸に変えています。

最後、svgで表示して終了です。

agraph.draw(<filename>, prog="dot", format="svg")にするとそのまま保存できます。

以上です。あとは、色を変えたりなどのおまけです。

おまけ

データ部分を以下に変更します。

nodes = [0, (1, {"label": "aaaaaaaa"}), 2, (3, {"color": "red", "fontcolor": "red"}), 4]
edges = [
    (0, 1), (1, 2), (2, 3), (3, 4), (4, 0),
    (0, 0), (0, 0),
    (1, 2), (1, 2), (1, 3), (1, 4),
    (3, 1), (4, 1, {"label": "A", "fontcolor": "blue", "color": "#ffaa00"})
    ]

ラベル名つけたり、色変えたりですね。

以下を参考にしながらグラフいじくってました。
http://www.graphviz.org/doc/info/attrs.html

おわり

大規模なグラフとか見てると心が楽しくなりますよね。

そういうグラフを眺めるときは、綺麗な表示が欲しいです。

かなり表示方法に幅があるみたいなので、とてもよいです。