如何无需手动定义节点位置生成航班网络水平布局图?
解决方案
要实现父节点与子节点沿水平线连接的层级布局,核心是先给每个节点分配层级属性,再用multipartite_layout生成布局,具体步骤如下:
1. 给节点分配层级属性
首先通过节点特征区分基地(不含-)和航班(含-),然后用BFS遍历图,从基地节点开始逐层分配层级:
# 判断节点是否为基地 def is_base(node): return '-' not in node # 初始化层级字典,基地节点为层级0 levels = {} base_nodes = [n for n in G.nodes if is_base(n)] for node in base_nodes: levels[node] = 0 # BFS遍历分配后续节点层级 visited = set(base_nodes) queue = base_nodes.copy() while queue: current = queue.pop(0) current_level = levels[current] for neighbor in G.neighbors(current): if neighbor not in visited: visited.add(neighbor) levels[neighbor] = current_level + 1 queue.append(neighbor) # 将层级属性添加到图中 nx.set_node_attributes(G, levels, 'layer')
2. 生成水平连接的层级布局
用multipartite_layout指定层级属性为layer,设置align='vertical'让同一层级的节点垂直排列,父节点与子节点的连接边保持水平:
import matplotlib.pyplot as plt # 生成布局 pos = nx.multipartite_layout(G, subset_key='layer', align='vertical', scale=3) # 绘制图形 nx.draw(G, pos, with_labels=True, node_size=1500, node_color='#aaddff', edge_color='#888888', font_size=10) plt.tight_layout() plt.show()
补充说明
- 如果图中存在循环(比如基地→航班→基地的闭环),BFS可能无法覆盖所有节点,可针对循环节点手动调整层级,或先拆分强连通分量再处理。
- 若希望层级沿垂直方向排列、边为垂直连接,可将
align参数改为'horizontal'。
内容的提问来源于stack exchange,提问作者Droid
相关产品推荐
相关产品推荐

