能否将NetworkX网络图叠加在OpenStreet风格PNG地图底图上?
用PNG城市地图作为底图叠加NetworkX行程网络图的可行性及实现方法
需求背景:
需绘制汽车行程网络图并叠加在街道风格地图上,现有两个DataFrame(locations存储位置、journeys存储行程),已用NetworkX构建网络图,但Basemap无道路细节、ArcGIS无法渲染地图,想尝试用PNG格式城市地图作为底图叠加,询问是否可行。
当然可行,以下是具体实现思路和步骤:
核心逻辑
把PNG底图加载到Matplotlib画布后,将NetworkX的节点、边通过经纬度与底图像素坐标的映射关系绘制在底图上方,核心是完成地理坐标到像素坐标的转换。
完整代码实现
1. 先安装依赖库
pip install pandas networkx matplotlib pillow
2. 代码示例
import pandas as pd import networkx as nx import matplotlib.pyplot as plt from PIL import Image # 加载位置与行程数据 locations = pd.DataFrame({'ID':[1,2,3], 'latitude':[40.710736,40.556678,40.778363], 'longitude':[-73.962940,-74.189803,-73.943489]}) journeys = pd.DataFrame({'from':[1,1,3], 'to':[2,3,2], 'count':[3,5,2] }) # 创建NetworkX有向图 graph = nx.from_pandas_edgelist(journeys, source='from', target='to', edge_attr='count', create_using=nx.DiGraph()) # 加载PNG底图(替换为你的本地地图路径) map_img = Image.open('city_map.png') img_width, img_height = map_img.size # 定义经纬度转像素坐标的函数 # 需提前获取PNG底图对应的经纬度边界(左下角/右上角) lon_min, lon_max = -74.2, -73.9 lat_min, lat_max = 40.5, 40.8 def latlon_to_pixel(lat, lon): # 计算经度对应的x像素 x = (lon - lon_min) / (lon_max - lon_min) * img_width # 反转y轴(Matplotlib原点在左上角,地理纬度原点在左下角) y = (lat_max - lat) / (lat_max - lat_min) * img_height return (x, y) # 生成节点的像素位置字典 pos = {} for idx, row in locations.iterrows(): pos[row['ID']] = latlon_to_pixel(row['latitude'], row['longitude']) # 绘制底图与网络图 fig, ax = plt.subplots(figsize=(10, 10)) ax.imshow(map_img) # 绘制节点、边 nx.draw_networkx_nodes(G=graph, pos=pos, nodelist=graph.nodes(), node_color='r', alpha=0.8, node_size=150, ax=ax) nx.draw_networkx_edges(G=graph, pos=pos, edge_color='g', alpha=0.5, arrows=True, ax=ax) # 可选:添加行程数量标签 nx.draw_networkx_edge_labels(G=graph, pos=pos, edge_labels={(u, v): d['count'] for u, v, d in graph.edges(data=True)}, ax=ax) # 隐藏坐标轴 ax.axis('off') plt.show()
关键注意事项
- 底图经纬度校准:必须准确获取PNG地图的经纬度边界(可从下载来源获取,或用工具标记边角坐标),否则节点位置会偏移。
- 坐标反转:Matplotlib的y轴方向与地理纬度相反,转换时必须反转y坐标。
- 透明度设置:调整节点、边的
alpha参数,避免遮挡底图的街道细节。
内容的提问来源于stack exchange,提问作者SlowBear
相关产品推荐
相关产品推荐

