Useful networkx drawing package

1. Introduction to NetworkX

        NetworkX is a Python library for creating, manipulating, and studying complex networks. It can create, analyze and visualize various types of networks (including directed and undirected graphs), such as social networks, Web graphs, biological networks, etc. NetworkX is capable of handling huge graphs with over 10 million nodes and over 100 million edges.

        NetworkX provides many graph algorithms and analysis tools, such as node degree, network diameter, shortest path, etc. You can also use it to discover community structures, perform cluster analysis of graphs, etc.

2. Drawing and traversing directed graphs

2.1 Drawing nodes and edges

# -*- 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()

as follows:

 Other common display layouts

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 Directed graph traversal

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 Specify node coordinates and color

Draw nodes, edges and labels respectively, and specify coordinates and colors

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()

as follows:

2.4 Different drawing strategies are used for edges with different weights

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')

as follows:

3. Weighted edges

3.1 Draw weighted edges

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()

as follows:

 Print edge weight value

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

3.2 Shortest | Long Path

# 两点之间最短路径
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

experiment

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. Properties of nodes and edges

4.1 Adding and modifying node attributes

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 Adding and modifying edge attributes

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})]

Guess you like

Origin blog.csdn.net/MusicDancing/article/details/132316258