Python案例如何用Networkx做网络分层

wen python案例 1

本文目录导读:

Python案例如何用Networkx做网络分层

  1. 基础分层布局 - 使用shell_layout
  2. 自定义分层布局
  3. 带颜色的分层可视化
  4. 交互式分层网络
  5. 动态分层网络(带动画)
  6. 使用建议

我来详细介绍一下如何使用NetworkX进行网络分层可视化,以下是几个实用的案例:

基础分层布局 - 使用shell_layout

import networkx as nx
import matplotlib.pyplot as plt
# 创建一个有向图
G = nx.DiGraph()
# 添加节点和边
edges = [
    ('A', 'B'), ('A', 'C'), ('A', 'D'),
    ('B', 'E'), ('B', 'F'),
    ('C', 'G'), ('C', 'H'),
    ('E', 'I'), ('F', 'I'), ('G', 'I'), ('H', 'I'),
    ('D', 'J'), ('J', 'K')
]
G.add_edges_from(edges)
# 定义每层的节点
layers = [
    ['A'],           # 第1层
    ['B', 'C', 'D'], # 第2层
    ['E', 'F', 'G', 'H', 'J'], # 第3层
    ['I', 'K']       # 第4层
]
# 使用shell_layout实现分层
pos = nx.shell_layout(G, nlist=layers)
# 绘制图形
plt.figure(figsize=(10, 8))
nx.draw(G, pos, with_labels=True, 
        node_color='lightblue',
        node_size=2000,
        font_size=12,
        font_weight='bold',
        arrows=True,
        arrowsize=20)
"网络分层布局 - shell_layout")
plt.show()

自定义分层布局

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
def hierarchical_layout(G, layers):
    """
    自定义分层布局函数
    参数:
    G: networkx图
    layers: 列表的列表,每层包含的节点
    """
    pos = {}
    layer_dist = 2.0  # 层间距离
    node_dist = 1.5   # 同层节点间距
    for layer_idx, layer_nodes in enumerate(layers):
        # 计算y坐标(从下到上)
        y = layer_idx * layer_dist
        # 计算x坐标
        n_nodes = len(layer_nodes)
        if n_nodes == 1:
            x_positions = [0]
        else:
            x_positions = np.linspace(
                -node_dist * (n_nodes - 1) / 2,
                node_dist * (n_nodes - 1) / 2,
                n_nodes
            )
        # 为每层的每个节点设置位置
        for node_idx, node in enumerate(layer_nodes):
            pos[node] = (x_positions[node_idx], y)
    return pos
# 示例2:更复杂的网络
G2 = nx.DiGraph()
# 添加更多节点和边
edges2 = [
    ('王总', '张经理'), ('王总', '李经理'),
    ('张经理', '赵主管'), ('张经理', '钱主管'),
    ('李经理', '孙主管'), ('李经理', '周主管'),
    ('赵主管', '员工1'), ('赵主管', '员工2'),
    ('钱主管', '员工3'),
    ('孙主管', '员工4'), ('孙主管', '员工5'),
    ('周主管', '员工6')
]
G2.add_edges_from(edges2)
# 定义分层(组织结构)
layers2 = [
    ['王总'],                     # CEO层
    ['张经理', '李经理'],         # 经理层
    ['赵主管', '钱主管', '孙主管', '周主管'],  # 主管层
    ['员工1', '员工2', '员工3', '员工4', '员工5', '员工6']  # 员工层
]
# 使用自定义分层布局
pos2 = hierarchical_layout(G2, layers2)
# 绘制
plt.figure(figsize=(12, 8))
nx.draw(G2, pos2, with_labels=True,
        node_color='lightgreen',
        node_size=2500,
        font_size=10,
        font_weight='bold',
        arrows=True,
        arrowsize=20,
        edge_color='gray')
"公司组织结构分层图")
plt.show()

带颜色的分层可视化

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
def colored_hierarchical_layout(G, layers, colors):
    """
    带颜色的分层布局
    """
    pos = {}
    layer_dist = 3.0
    for layer_idx, layer_nodes in enumerate(layers):
        y = layer_idx * layer_dist
        n_nodes = len(layer_nodes)
        if n_nodes == 1:
            x_positions = [0]
        else:
            x_positions = np.linspace(
                -layer_dist * (n_nodes - 1) / 2,
                layer_dist * (n_nodes - 1) / 2,
                n_nodes
            )
        for node_idx, node in enumerate(layer_nodes):
            pos[node] = (x_positions[node_idx], y)
    return pos
# 更复杂的网络示例
G3 = nx.DiGraph()
# 分层数据
layers3 = [
    ['数据源'],                    # 第1层
    ['数据采集', '数据清洗'],      # 第2层
    ['特征工程', '模型训练'],      # 第3层
    ['部署'],                      # 第4层
    ['监控', '反馈']              # 第5层
]
# 添加边
edges3 = [
    ('数据源', '数据采集'), ('数据源', '数据清洗'),
    ('数据采集', '特征工程'),
    ('数据清洗', '特征工程'),
    ('特征工程', '模型训练'),
    ('模型训练', '部署'),
    ('部署', '监控'), ('部署', '反馈')
]
G3.add_edges_from(edges3)
# 为每层定义颜色
layer_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
# 计算位置
pos3 = colored_hierarchical_layout(G3, layers3)
# 为每个节点分配颜色
node_colors = []
for node in G3.nodes():
    for layer_idx, layer_nodes in enumerate(layers3):
        if node in layer_nodes:
            node_colors.append(layer_colors[layer_idx])
            break
# 绘制
plt.figure(figsize=(14, 10))
nx.draw(G3, pos3, with_labels=True,
        node_color=node_colors,
        node_size=3000,
        font_size=12,
        font_weight='bold',
        font_color='black',
        arrows=True,
        arrowsize=25,
        edge_color='gray',
        width=2,
        alpha=0.9)
# 添加图例
for idx, (layer_name, color) in enumerate(zip(
    ['数据源层', '数据处理层', '模型构建层', '部署层', '监控层'],
    layer_colors
)):
    plt.scatter([], [], c=color, label=layer_name, s=200)
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))"机器学习流水线分层架构", fontsize=16, pad=20)
plt.tight_layout()
plt.show()

交互式分层网络

import networkx as nx
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch
import numpy as np
def draw_fancy_hierarchical_network(G, layers):
    """
    绘制精美的分层网络图
    """
    fig, ax = plt.subplots(figsize=(15, 10))
    # 计算位置
    pos = {}
    layer_dist = 3.0
    node_dist = 2.0
    for layer_idx, layer_nodes in enumerate(layers):
        y = layer_idx * layer_dist
        n_nodes = len(layer_nodes)
        if n_nodes == 1:
            x_positions = [0]
        else:
            x_positions = np.linspace(
                -node_dist * (n_nodes - 1) / 2,
                node_dist * (n_nodes - 1) / 2,
                n_nodes
            )
        for node_idx, node in enumerate(layer_nodes):
            pos[node] = (x_positions[node_idx], y)
    # 绘制边
    for edge in G.edges():
        x1, y1 = pos[edge[0]]
        x2, y2 = pos[edge[1]]
        # 绘制曲线箭头
        ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
                   arrowprops=dict(arrowstyle='->',
                                 color='gray',
                                 lw=2,
                                 connectionstyle='arc3,rad=0.2'))
    # 绘制节点
    for node, (x, y) in pos.items():
        # 找到节点所属的层
        node_color = 'lightblue'
        for layer_idx, layer_nodes in enumerate(layers):
            if node in layer_nodes:
                # 根据层级设置颜色
                colors = plt.cm.Set3(np.linspace(0, 1, len(layers)))
                node_color = colors[layer_idx]
                break
        # 绘制圆角矩形节点
        rect = FancyBboxPatch((x-0.5, y-0.3), 1, 0.6,
                             boxstyle="round,pad=0.1",
                             facecolor=node_color,
                             edgecolor='black',
                             linewidth=2)
        ax.add_patch(rect)
        # 添加标签
        ax.text(x, y, node, ha='center', va='center',
               fontsize=12, fontweight='bold')
    # 添加层标签
    layer_labels = ['数据层', '处理层', '分析层', '展示层']
    for layer_idx, label in enumerate(layer_labels):
        y = layer_idx * layer_dist
        ax.text(-node_dist * 2, y, label,
               fontsize=14, fontweight='bold',
               ha='center', va='center',
               bbox=dict(boxstyle='round,pad=0.3',
                        facecolor='wheat',
                        edgecolor='gray'))
    ax.set_xlim(-node_dist * 3, node_dist * 3)
    ax.set_ylim(-layer_dist, layer_dist * len(layers))
    ax.axis('off')
    plt.title("精致分层网络可视化", fontsize=16)
    return fig, ax
# 使用示例
G4 = nx.DiGraph()
layers4 = [
    ['传感器1', '传感器2', '传感器3'],
    ['数据处理器'],
    ['分析引擎'],
    ['仪表盘']
]
edges4 = [
    ('传感器1', '数据处理器'),
    ('传感器2', '数据处理器'),
    ('传感器3', '数据处理器'),
    ('数据处理器', '分析引擎'),
    ('分析引擎', '仪表盘')
]
G4.add_edges_from(edges4)
draw_fancy_hierarchical_network(G4, layers4)
plt.show()

动态分层网络(带动画)

import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
def create_animated_hierarchy():
    fig, ax = plt.subplots(figsize=(12, 8))
    G = nx.DiGraph()
    # 定义层和节点
    layers = {
        0: ['A'],
        1: ['B', 'C'],
        2: ['D', 'E', 'F'],
        3: ['G', 'H']
    }
    edges = [
        ('A', 'B'), ('A', 'C'),
        ('B', 'D'), ('B', 'E'),
        ('C', 'F'), ('C', 'D'),
        ('D', 'G'), ('E', 'H'), ('F', 'H')
    ]
    G.add_edges_from(edges)
    # 计算初始位置
    pos = {}
    for layer, nodes in layers.items():
        y = -layer
        n_nodes = len(nodes)
        if n_nodes == 1:
            x_pos = [0]
        else:
            x_pos = np.linspace(-1.5, 1.5, n_nodes)
        for i, node in enumerate(nodes):
            pos[node] = (x_pos[i], y)
    def update(frame):
        ax.clear()
        # 动态颜色变化
        colors = plt.cm.rainbow(frame / 100)
        nx.draw(G, pos, with_labels=True,
                node_color=[colors] * G.number_of_nodes(),
                node_size=2000,
                font_size=12,
                font_weight='bold',
                arrows=True,
                arrowsize=20,
                ax=ax)
        ax.set_title(f"动态分层网络 - 帧 {frame}", fontsize=14)
        ax.set_xlim(-3, 3)
        ax.set_ylim(-4, 1)
    ani = animation.FuncAnimation(fig, update, frames=100, 
                                 interval=200, blit=False)
    return ani
# 创建动画(需要取消注释来运行)
# ani = create_animated_hierarchy()
# plt.show()

使用建议

  1. 选择合适的布局

    • shell_layout:适合简单的分层结构
    • hierarchical_layout:适合自定义复杂分层
    • spring_layout:适合显示节点间的关系强度
  2. 颜色使用

    • 每层使用不同颜色
    • 同层节点使用相似色系
    • 重要节点使用突出颜色
  3. 交互性

    • 可以使用 plotlybokeh 添加交互
    • 添加鼠标悬停信息
    • 实现拖动和缩放功能

这些案例涵盖了从基础到高级的各种NetworkX分层布局方法,你可以根据具体需求选择合适的方式。

抱歉,评论功能暂时关闭!