如何用NetworkX绘制带经纬度节点与边标签的仓储位置图
仓储位置NetworkX绘图解决方案
问题背景
样本数据集
| src_node | dest_node | src_edge | dest_edge | src_lat-src_lon | dest_lat-dest_lon |
|---|---|---|---|---|---|
| 1 | 3 | a | x | 38.89-77.03 | 38.91-77.05 |
| 3 | 2 | b | y | 38.91-77.05 | 38.82-77.01 |
| 4 | 1 | c | z | 38.93-77.06 | 38.89-77.03 |
原尝试代码
import network as nx import matplotlib.pyplot as plt data = [[1, 3, 'a', 'x', '38.89-77.03', '38.91-77.05'],[3, 2, 'b', 'y', '38.91-77.05', '38.82-77.01'],[4, 1, 'c', 'z', '38.93-77.06', '38.89-77.03']] temp = pd.DataFrame(data, columns=['src_node', 'dest_node','src_edge','dest_edge','src_lat-src_lon', 'dest_lat-dest_lon']) def plot_graph(nodes, edges, labels=False, node_size=False, node_color='r'): plt.figure(figsize=(10,10)) G = nx.DiGraph() G.add_nodes_from(nodes) G.add_edges_from(edges) nx.draw(G, with_labels=labels, node_color=node_color) plt.show() plot_graph(nodes=pd.unique(temp['src_node'].append(temp['dest_node'])), edges=[tuple(row) for row in temp[['src_node','dest_node']].values], labels=True, node_color='orange')
需求
- 根据经纬度值在图中排列节点
- 给箭头起点添加
src_edge标签、箭头终点添加dest_edge标签 - 支持邻接关系分析
解决方案
完整代码
import networkx as nx import matplotlib.pyplot as plt import pandas as pd data = [[1, 3, 'a', 'x', '38.89-77.03', '38.91-77.05'], [3, 2, 'b', 'y', '38.91-77.05', '38.82-77.01'], [4, 1, 'c', 'z', '38.93-77.06', '38.89-77.03']] temp = pd.DataFrame(data, columns=['src_node', 'dest_node','src_edge','dest_edge', 'src_lat-src_lon', 'dest_lat-dest_lon']) # 1. 构建节点经纬度位置字典 pos = {} # 读取源节点经纬度 for idx, row in temp.iterrows(): node = row['src_node'] lat_lon = row['src_lat-src_lon'].split('-') # NetworkX绘图中x对应经度,y对应纬度,所以位置格式为(经度, 纬度) pos[node] = (float(lat_lon[1]), float(lat_lon[0])) # 补全目标节点中未覆盖的经纬度 for idx, row in temp.iterrows(): node = row['dest_node'] if node not in pos: lat_lon = row['dest_lat-dest_lon'].split('-') pos[node] = (float(lat_lon[1]), float(lat_lon[0])) # 2. 创建有向图并添加边属性 G = nx.DiGraph() nodes = pd.unique(pd.concat([temp['src_node'], temp['dest_node']])) G.add_nodes_from(nodes) # 给边绑定src_edge和dest_edge属性 for idx, row in temp.iterrows(): G.add_edge(row['src_node'], row['dest_node'], src_edge=row['src_edge'], dest_edge=row['dest_edge']) # 3. 绘图渲染 plt.figure(figsize=(12, 10)) # 绘制节点 nx.draw_networkx_nodes(G, pos, node_size=1500, node_color='orange', edgecolors='black') # 绘制有向边 nx.draw_networkx_edges(G, pos, arrowstyle='->', arrowsize=20, edge_color='gray') # 绘制节点标签 nx.draw_networkx_labels(G, pos, font_size=12, font_weight='bold') # 绘制边起点标签(src_edge),靠近源节点 src_edge_labels = {(u, v): d['src_edge'] for u, v, d in G.edges(data=True)} nx.draw_networkx_edge_labels(G, pos, edge_labels=src_edge_labels, label_pos=0.1, font_size=10, font_color='blue') # 绘制边终点标签(dest_edge),靠近目标节点 dest_edge_labels = {(u, v): d['dest_edge'] for u, v, d in G.edges(data=True)} nx.draw_networkx_edge_labels(G, pos, edge_labels=dest_edge_labels, label_pos=0.9, font_size=10, font_color='red') plt.title('仓储位置邻接关系图', fontsize=14) plt.axis('off') plt.show() # 4. 邻接关系分析示例 print("节点邻接关系:") for node in G.nodes(): print(f"节点{node}的出边: {list(G.out_edges(node))}") print(f"节点{node}的入边: {list(G.in_edges(node))}")
关键实现说明
按经纬度排列节点:
从数据中拆分经纬度字符串并转换为数值,构建pos字典存储每个节点的地理坐标(注意NetworkX的坐标格式为(经度, 纬度)),绘图时传入该字典即可让节点按真实位置排列。边标签设置:
添加边时将src_edge和dest_edge作为边属性存入图中,分别创建两种标签字典,通过label_pos参数控制标签位置(0.1靠近源节点,0.9靠近目标节点),用颜色区分两种标签。邻接关系分析:
利用NetworkX提供的out_edges()和in_edges()方法,可直接获取每个节点的出邻接、入邻接关系,支持后续路径查找、连通性分析等操作。
原代码错误修正
- 导入错误:
import network as nx改为import networkx as nx - 依赖缺失:添加
import pandas as pd - 节点合并方式:
temp['src_node'].append(temp['dest_node'])改为pd.concat([temp['src_node'], temp['dest_node']])(适配新版pandas)
内容的提问来源于stack exchange,提问作者skiddy
相关产品推荐
相关产品推荐

