[python] NetworkXに基づくネットワークグラフ描画の実装



Implementation Network Graph Drawing Based Networkx



記事のディレクトリ

コードのダウンロードアドレス
ネットワーク図(または図やグラフ)は、エンティティのグループ間の相互接続を示します。各エンティティは、1つ以上のノードで表されます。ノード間の接続は、リンク(またはエッジ)で表されます。ネットワークの理論と実装は幅広い研究分野です。ネットワーク全体がこれに取り組むことができます。たとえば、ネットワークは有向または無向、加重または無加重にすることができます。多くの異なる入力形式があります。この領域をガイドするために、次の例を推奨される順序で実行することをお勧めします。このツールに関して、私は主に依存していることに注意してください NetworkX ライブラリ(バージョン2.4)。ただし、使用も検討する必要があることに注意してください グラフツール 、特に高次元ネットワークに関しては。この章の主な内容は次のとおりです。

  1. パンダの基本グリッドからパンダのデータフレームから基本ネットワークを描画
  2. カスタムNetworkXグラフの外観
  3. ネットワークレイアウトの可能性
  4. 有向または無向ネットワーク
  5. ネットワークノードに色をマッピングする
  6. ネットワークの端に色をマッピングします
  7. ネットワークチャートの背景色
  8. 相関行列からのネットワーク
    NetworkXのインストール:
pip install networkx==2.4

この記事は以下を参照しています:



https://python-graph-gallery.com/network-chart/

from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = 'all'

1.パンダのデータフレームから基本的なネットワークを描画します

この例は、おそらく実装できる最も基本的なネットワーク図です。ネットワークグラフはノードで構成されています。これらのノードは、エッジによって相互に接続されています。したがって、基本的な形式はデータフレームであり、各行は接続を記述します。ここでは、4本の線を使用して、このグラフの4つの接続を説明するデータフレームを作成します。したがって、接続にcsvファイルが付属している場合は、ファイルをロードして視覚化する準備をしてください。 FROMは開始点を表し、toは終了点を表します。



# libraries import module import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with 4 connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) df # Build your graph # Draw a network diagram, the result may be different each time G=nx.from_pandas_edgelist(df, 'from', 'to') # Plot it nx.draw(G, with_labels=True) plt.show()
から
0 D
1 B
C IS
3 C

png

2.カスタムNetworkXグラフの外観カスタムNetworkXグラフの外観

それでは、チャートの外観をカスタマイズするためのパラメーターを見てみましょう。カスタマイズは、ノード、ノードラベル、エッジの3つの主要なカテゴリに分類されます。

  • ノード
  • ラベル
  • エッジ
  • まとめすべて
## Nodes # libraries Load library import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to') # Graph with Custom nodes: Custom table # with_labels Whether to display labels, node_size node size, node_color node color, node_shape node shape, alpha transparency, linewidths line width nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', node_shape='s', alpha=0.5, linewidths=10) plt.show()
から
0 D
1 B
C IS
3 C

png



## Labels Labels # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to') # Custom the edges: # font_size label font size, font_color label font color, font_weight font form nx.draw(G, with_labels=True, node_size=1500, font_size=25, font_color='yellow', font_weight='bold') plt.show()
から
0 D
1 B
C IS
3 C

png

## Edges # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to') # Chart with Custom edges: # width side line width, edge_color side line color nx.draw(G, with_labels=True, width=10, edge_color='skyblue', style='solid')
から
0 D
1 B
C IS
3 C

png

## Summary All # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to') # All together we can do something fancy nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', node_shape='o', alpha=0.5, linewidths=4, font_size=25, font_color='grey', font_weight='bold', width=2, edge_color='grey')
から
0 D
1 B
C IS
3 C

png

3.ネットワークレイアウトの可能性

実際、各ノードの最適な位置を計算するアルゴリズムがあります。 NetworkXは、いくつかのアルゴリズムを開発および提案しています。このページでは、同じ小さなデータセットを取得し、それに異なるレイアウトアルゴリズムを適用することで、この概念を説明します。どちらが最適かわからない場合は、デフォルトでデフォルトとして設定してください。デフォルトのSpringレイアウト

# libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A','E','F','E','G','G','D','F'], 'to':['D', 'A', 'E','C','A','F','G','D','B','G','C']}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to')
から
0 D
1 B
C IS
3 C
4 IS
5 F F
6 IS G
7 G D
8 G B
9 D G
10 F C
# Fruchterman Reingold Fruchterman Reingold guide layout algorithm layout nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', pos=nx.fruchterman_reingold_layout(G)) plt.title('fruchterman_reingold') Text(0.5, 1.0, 'fruchterman_reingold')

png

# Circular circular layout nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', pos=nx.circular_layout(G)) plt.title('circular') Text(0.5, 1.0, 'circular')

png

# Random random layout nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', pos=nx.random_layout(G)) plt.title('random') Text(0.5, 1.0, 'random')

png

# Spectral Spectral layout nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', pos=nx.spectral_layout(G)) plt.title('spectral') Text(0.5, 1.0, 'spectral')

png

# Spring Jump layout nx.draw(G, with_labels=True, node_size=1500, node_color='skyblue', pos=nx.spring_layout(G)) plt.title('spring') Text(0.5, 1.0, 'spring')

png

4.有向または無向ネットワーク

ネットワークグラフは、有向ネットワークと無向ネットワークの2つの主要なカテゴリに分類できます。方向性がある場合は、2つのノード間にフローの概念があり、他の場所に移動する場所が残ります。お金がA社からB社に流れるように。これが、方向を示す左側のチャートの矢印を(ある程度)見ることができる理由です。たとえば、トラフィックはBからAに流れます。無向の場合、これら2つのノード間には1つのリンクしかありません。たとえば、AさんとBさんは友達です。
グラフを生成するときは、ニーズに合った関数を使用する必要があります。無向(デフォルト)の場合はGraph()、有向グラフの場合はDiGraphです。

# libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt ## DIRECTED directed graph # Build a dataframe with your connections # This time a pair can appear 2 times, in one side or in the other! df = pd.DataFrame({ 'from':['D', 'A', 'B', 'C','A'], 'to':['A', 'D', 'A', 'E','C']}) df # Build your graph. Note that we use the DiGraph function to create the graph! # create_using=nx.DiGraph() creates a directed graph, the default is an undirected graph G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.DiGraph()) # Make the graph directed graph nx.draw(G, with_labels=True, node_size=1500, alpha=0.3, arrows=True)
から
0 D
1 D
B
3 C IS
4 C

png

# UNDIRECTED Undirected graph # Build a dataframe with your connections # This time a pair can appear 2 times, in one side or in the other! df = pd.DataFrame({ 'from':['D', 'A', 'B', 'C','A'], 'to':['A', 'D', 'A', 'E','C']}) df # Build your graph. Note that we use the Graph function to create the graph! G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph()) # Make the graph nx.draw(G, with_labels=True, node_size=1500, alpha=0.3, arrows=True) plt.title('UN-Directed')
から
0 D
1 D
B
3 C IS
4 C
Text(0.5, 1.0, 'UN-Directed')

png

5.ネットワークノードに色をマッピングします

一般的なタスクは、ネットワークグラフの各ノードをその機能に従って色付けすることです(これをマッピング色と呼びます)。これにより、より多くの情報をチャートに表示できます。 2つの可能性があります:

  1. マップするフィーチャは数値です。次に、連続カラースケールを使用します。左の写真では、AはCよりも暗く、Bよりも暗くなっています。
  2. この機能は分類されています。右の写真では、AとBは同じグループに属しており、DとEはグループ化されており、Cは彼のグループに単独で存在しています。分類カラースケールを使用しました。

通常、2つのテーブルを使用します。最初のものはノード間のリンクを提供します。 2つ目は、各ノードの機能を提供します。これらの2つのファイルは次のようにリンクできます。

  • 連続カラー
  • 分類色
## Continuous color scale Continuous color scale # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) # And a data frame with characteristics for your nodes carac = pd.DataFrame({ 'ID':['A', 'B', 'C','D','E'], 'myvalue':['123','25','76','12','34'] }) # Settings carac # Build your graph G =nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() ) # The order of the node for networkX is the following order: # Node order G.nodes() # Thus, we cannot give directly the 'myvalue' column to netowrkX, we need to arrange the order! # Here is the tricky part: I need to reorder carac, to assign the good color to each node # Set the color according to myvalue and match the node order and ID number carac = carac.set_index('ID') carac =carac.reindex(G.nodes()) carac # Plot it, providing a continuous color scale with cmap: # node_color sets the color, the input must be a float array or an int value cmap color bar nx.draw(G, with_labels=True, node_color=np.array(carac['myvalue'].values,dtype='float32'), cmap=plt.cm.Blues)
ID myvalue
0 123
1 B 25
C 76
3 D 12
4 IS 3. 4
NodeView(('A', 'D', 'B', 'C', 'E'))
myvalue
ID
123
D 12
B 25
C 76
IS 3. 4

png

## Categorical color scale Continuous color # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C']}) # And a data frame with characteristics for your nodes carac = pd.DataFrame({ 'ID':['A', 'B', 'C','D','E'], 'myvalue':['group1','group1','group2','group3','group3'] }) # Build your graph # Create graph G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() ) # The order of the node for networkX is the following order: # Print node order G.nodes() # Thus, we cannot give directly the 'myvalue' column to netowrkX, we need to arrange the order! # Here is the tricky part: I need to reorder carac to assign the good color to each node carac= carac.set_index('ID') # Set the value according to the node order carac=carac.reindex(G.nodes()) # And I need to transform my categorical column in a numerical value: group1->1, group2->2... # Set category carac['myvalue']=pd.Categorical(carac['myvalue']) carac['myvalue'].cat.codes # Custom the nodes: nx.draw(G, with_labels=True, node_color=carac['myvalue'].cat.codes, cmap=plt.cm.Set1, node_size=1500) NodeView(('A', 'D', 'B', 'C', 'E')) ID A 0 D 2 B 0 C 1 E 2 dtype: int8

png

6.ネットワークの端に色をマッピングします

ネットワークのエッジごとに関数があると仮定します。たとえば、この関数は、このリンクで表される金額(デジタル値)、またはそれが発生する大陸(カテゴリ値)の場合があります。この変数に基づいてエッジを異なるものにする必要があります。

  • 数値
  • カテゴリカル
## numerical # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections # value Set link value df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C'], 'value':[1, 10, 5, 5]}) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() ) # Custom the nodes: #edge_color Set the color of the edge nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_color=df['value'], width=10.0, edge_cmap=plt.cm.Blues)
から
0 D 1
1 B 10
C IS 5
3 C 5

png

## categorical # libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections # value setting type df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C'], 'value':['typeA', 'typeA', 'typeB', 'typeB']}) df # And I need to transform my categorical column in a numerical value typeA->1, typeB->2... # Convert to category df['value']=pd.Categorical(df['value']) df['value'].cat.codes # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() ) # Custom the nodes: nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_color=df['value'].cat.codes, width=10.0, edge_cmap=plt.cm.Set2)
から
0 D typeA
1 B typeA
C IS typeB
3 C typeB
0 0 1 0 2 1 3 1 dtype: int8

png

7.ネットワークチャートの背景色

fig.set_facecolor()を使用して、ネットワーク図の背景色を変更できます。 pngの背景色を維持したい場合は、fig.get_facecolorを追加する必要があることに注意してください。

# libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # Build a dataframe with your connections df = pd.DataFrame({ 'from':['A', 'B', 'C','A'], 'to':['D', 'A', 'E','C'] }) df # Build your graph G=nx.from_pandas_edgelist(df, 'from', 'to', create_using=nx.Graph() ) # Custom the nodes: fig = plt.figure() nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_color='white') # Set background color fig.set_facecolor('#00000F') # If you want to save the figure to png: # To save the image, you need to set facecolor=fig.get_facecolor(), otherwise the background color is white # plt.savefig('yourname.png', facecolor=fig.get_facecolor(),dpi=300)
から
0 D
1 B
C IS
3 C

png

8.相関行列からのネットワーク

このページでは、相関ネットワーク(相関行列に基づくネットワーク)の描画方法について説明します。 10人の人がいて、お互いの親密な関係を知っているとします。これらの関係は、ネットワークで表すことができます。誰もがノードです。 2人が十分に接近している場合(しきい値を設定)、それらはエッジによってリンクされます。それは人口統計学的構造を示します!

# libraries import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt # I build a data set: 10 individuals and 5 variables for each ind1=[5,10,3,4,8,10,12,1,9,4] ind5=[1,1,13,4,18,5,2,11,3,8] # Build matrix df = pd.DataFrame({ 'A':ind1, 'B':ind1 + np.random.randint(10, size=(10)) , 'C':ind1 + np.random.randint(10, size=(10)) , 'D':ind1 + np.random.randint(5, size=(10)) , 'E':ind1 + np.random.randint(5, size=(10)), 'F':ind5, 'G':ind5 + np.random.randint(5, size=(10)) , 'H':ind5 + np.random.randint(5, size=(10)), 'I':ind5 + np.random.randint(5, size=(10)), 'J':ind5 + np.random.randint(5, size=(10))}) df # Calculate the correlation between individuals. We have to transpose first, because the corr function calculate the pairwise correlations between columns. # Calculate correlation corr = df.corr() corr # Transform it in a links data frame (3 columns only): # Flatten the correlation coefficient matrix links = corr.stack().reset_index() # Set column name links.columns = ['var1', 'var2','value'] #links # Keep only correlation over a threshold and remove self correlation (cors (A,A)=1) # Eliminate rows with the same number and rows with correlation coefficient less than 0.8 links_filtered=links.loc[ (links['value'] > 0.8) & (links['var1'] != links['var2']) ] #links_filtered # Build your graph # Drawing G=nx.from_pandas_edgelist(links_filtered, 'var1', 'var2') # Plot the network: nx.draw(G, with_labels=True, node_color='orange', node_size=500, edge_color='black', linewidths=5, font_size=15)
B C D IS F G H J
0 5 13 6 8 8 1 4 1 3
1 10 19 10 14 12 1 3 4 4 5
3 9 3 5 3 13 17 13 14 15
3 4 6 5 4 5 4 7 4 7 4
4 8 13 9 12 10 18 19 19 20 19
5 10 13 13 十一 十一 5 8 9 7 9
6 12 16 14 15 13 3 6 3
7 1 7 6 3 4 十一 14 14 14 十一
8 9 十一 9 9 9 3 4 5 7 5
9 4 9 4 7 4 8 8 8 10 8
B C D IS F G H J
1.000000 0.816480 0.901905 0.936634 0.949857 -0.409401 -0.505922 -0.327200 -0.325622 -0.276172
B 0.816480 1.000000 0.706978 0.928908 0.876425 -0.380840 -0.440560 -0.291830 -0.369119 -0.214817
C 0.901905 0.706978 1.000000 0.830659 0.926892 -0.343944 -0.416735 -0.200915 -0.245105 -0.230368
D 0.936634 0.928908 0.830659 1.000000 0.939070 -0.282163 -0.397256 -0.212778 -0.229146 -0.151093
IS 0.949857 0.876425 0.926892 0.939070 1.000000 -0.412766 -0.488815 -0.301198 -0.346611 -0.278961
F -0.409401 -0.380840 -0.343944 -0.282163 -0.412766 1.000000 0.972397 0.968543 0.975579 0.965554
G -0.505922 -0.440560 -0.416735 -0.397256 -0.488815 0.972397 1.000000 0.952668 0.923379 0.957782
H -0.327200 -0.291830 -0.200915 -0.212778 -0.301198 0.968543 0.952668 1.000000 0.956089 0.973569
-0.325622 -0.369119 -0.245105 -0.229146 -0.346611 0.975579 0.923379 0.956089 1.000000 0.927947
J -0.276172 -0.214817 -0.230368 -0.151093 -0.278961 0.965554 0.957782 0.973569 0.927947 1.000000

png