便利な networkx 描画パッケージ

1. NetworkX の概要

        NetworkX は、複雑なネットワークを作成、操作、および研究するための Python ライブラリです。ソーシャル ネットワーク、Web グラフ、生物学的ネットワークなど、さまざまなタイプのネットワーク (有向グラフおよび無向グラフを含む) を作成、分析、視覚化できます。NetworkX は、1,000 万以上のノードと 1 億以上のエッジを持つ巨大なグラフを処理できます。

        NetworkX は、ノード次数、ネットワーク直径、最短パスなど、多くのグラフ アルゴリズムと分析ツールを提供します。また、コミュニティ構造を発見したり、グラフのクラスター分析を実行したりするために使用することもできます。

2. 有向グラフの描画と走査

2.1 ノードとエッジの描画

# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# 创建空的有向图的对象
G = nx.DiGraph()
# 添加节点
G.add_node('A')
G.add_nodes_from(['B', 'C', 'D', 'E']) 
G.remove_nodes_from(['C','D'])  # 删除集合中的节点
# 添加有向边
G.add_edge('A', 'B')
G.add_edges_from([('B','C'),('B', 'D'),('C', 'E')]) 

# 进行图的绘制
layout = nx.spring_layout(G)  # 节点布局,也是节点坐标
nx.draw(G, layout, pos=layout, node_color='red', edge_color='black', 
        with_labels=True, font_size=10, node_size=300)
plt.show()

次のように:

 その他の一般的な表示レイアウト

layout = nx.circular_layout(G)  # 生成圆形节点布局
layout = nx.random_layout(G)  # 生成随机节点布局
layout = nx.shell_layout(G)   # 生成同心圆节点布局
layout = nx.spectral_layout(G)  # 利用图拉普拉斯特征向量生成节点布局
layout = nx.kamada_kawai_layout(G)  # 使用Kamada-Kawai路径长度代价函数生成布局

2.2 有向グラフ走査

print(G.nodes)  # 节点列表
# ['A', 'B', 'C', 'D', 'E']
print(G.edges)  # 边列表
# [('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'E')]
for node in G.nodes():
    print("节点>>>", node)
    in_degree = G.in_degree(node)
    print("入度:", in_degree)
    out_degree = G.out_degree(node)
    print("出度:", out_degree)
    neighbors = G.neighbors(node)
    print("邻居节点:", list(neighbors))

2.3 ノードの座標と色の指定

ノード、エッジ、ラベルをそれぞれ描画し、座標と色を指定します

net_grid = nx.DiGraph() 
list_net_nodes = [1, 2, 3, 4, 5]  # 节点
list_net_edges = [(1,  3), (3, 5), (5, 4), (4, 2)]  # 边
pos = {1: (1, 1), 2: (12, 1), 3: (2, 2), 4: (4, 2), 5: (3, 3)}  # 节点坐标
net_grid.add_nodes_from(list_net_nodes)   
net_grid.add_edges_from(list_net_edges)  
# ------ 画节点和边 ------- (在指定坐标位置)
nx.draw_networkx_nodes(G=net_grid, pos=pos, nodelist=list_net_nodes, node_size=30, node_shape='o', node_color='#ff0000|red')  # 画节点
nx.draw_networkx_edges(net_grid, pos, list_net_edges)  # 画边
# ------ 画节点标签 ------- 
dict_nodes_labels = dict(zip(list_net_nodes, list_net_nodes))  # 节点对应的标签
# {1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
nx.draw_networkx_labels(net_grid, pos, dict_nodes_labels) # 画标签
plt.show()

次のように:

2.4 異なる重みを持つエッジには異なる描画戦略が使用されます

e_large = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 0.5]
e_small = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 0.5]
nx.draw_networkx_nodes(G, pos, node_size=700)
nx.draw_networkx_edges(G, layout, edgelist=e_large, width=6)  # 画大权重边
nx.draw_networkx_edges(G, layout, edgelist=e_small, width=6, alpha=0.5, edge_color='b', style='dashed')  # 画小权重边
nx.draw_networkx_labels(G, layout, font_size=20, font_family='sans-serif')

次のように:

3. 重み付けされたエッジ

3.1 重み付けされたエッジを描画する

G = nx.DiGraph()
# 直接创建边(包括两个节点), 并设置边的权重
G.add_edge('A', 'B', weight=3)
G.add_weighted_edges_from([('B','C',5), ('C','D',2), ('C','E',5)])

# ---进行图的绘制---
layout = nx.spring_layout(G)  # 选择布局算法;
# 获取边的权重
labels = nx.get_edge_attributes(G, 'weight')
# {('A', 'B'): 3, ('B', 'C'): 5, ('C', 'D'): 2, ('C', 'E'): 5}
# 绘制带有权重的边
nx.draw(G, layout, with_labels=True)
nx.draw_networkx_edge_labels(G, layout, edge_labels=labels)  # 添加权重
plt.show()

次のように:

 プリントエッジウェイト値

# 获取边的权重值列表
print(labels.values())
# dict_values([3, 5, 2, 5])
print("最大权重的边:", max(weights))
print("最小权重的边:", min(weights))

3.2 最短 | 長いパス

# 两点之间最短路径
def get_shortest_path(graph, source, target):
    try:
        shortest_path = nx.shortest_path(graph, source, target)
        return shortest_path
    except nx.exception.NetworkXNoPath:
        return "不存在最短路径"

# 两点之间最长路径
def get_longest_path(graph, source, target):
    all_paths = nx.all_simple_paths(graph, source, target)
    longest_path = max(all_paths, key=len)
    return longest_path

実験

G = nx.DiGraph()
G.add_edge('A', 'B', weight=3)
G.add_edge('A', 'C', weight=5)
G.add_edge('B', 'C', weight=2)
G.add_edge('B', 'D', weight=4)
G.add_edge('C', 'D', weight=1)

# 输出边权重
for u, v, data in G.edges(data=True):
# for u,v,data in G.edges(data='weight'):
    print(u, v, data)

print("最短路径:", get_shortest_path(G, 'A', 'D'))
# ['A', 'B', 'D']
print("最长路径:", get_longest_path(G, 'A', 'D'))
# ['A', 'B', 'C', 'D']

# 按照权重求取最短路径
print("最短路径:", nx.dijkstra_path(G, 'A', 'D', weight='weight'))
# ['A', 'C', 'D']
print("最短距离:", nx.dijkstra_path_length(G, 'A', 'D', weight='weight'))
# 6

4. ノードとエッジのプロパティ

4.1 ノード属性の追加と変更

G.add_node('jack', age='16')  # 在添加节点时分配节点属性
print(G.nodes(data=True))
# [('jack', {'age': '16'})]
G.nodes['jack']['age'] = '18'  # 通过G.nodes来添加或修改属性
G.add_nodes_from(['tom', 'jerry'], age='18')  # 从集合中添加节点时分配属性
print(G.nodes(data=True))
# [('jack', {'age': '18'}), ('tom', {'age': '18'}), ('jerry', {'age': '18'})]

4.2 エッジ属性の追加と変更

G.add_edge(1, 2, weight=10)  # 在添加边时分配属性
G.add_edges_from([(3, 4, {'hight': 10}), (1, 4, {'hight': 'unknow'})])
G[1][2]['weight'] = 100000  # 通过G来添加或修改属性
print(G.edges(data=True))
# [(1, 2, {'weight': 100000}), (1, 4, {'hight': 'unknow'}), (3, 4, {'hight': 10})]

おすすめ

転載: blog.csdn.net/MusicDancing/article/details/132316258