如何在OSMnx中绘制子图?并添加节点标注与图例
实现双生子图并排+节点标注+图例的解决方案
核心问题解决:绑定子图Axes对象
你之前没得到预期结果,核心原因是绘图时没明确指定要画在哪个子图上。用plt.subplots创建子图后,必须给NetworkX的绘图函数传入ax参数,绑定对应的子图轴。
完整代码示例
假设你用NetworkX处理图数据,以下是可直接参考的实现:
import matplotlib.pyplot as plt import networkx as nx from matplotlib.lines import Line2D # 替换为你的实际图数据 G = nx.Graph() # 你的图结构 nodes_pos = nx.spring_layout(G) # 节点位置(也可使用自定义坐标) # 提前计算好的路径边集合 path_edges_549 = [(u, v) for u, v in G.edges() if v in nx.shortest_path(G, 549, u)] path_edges_10 = [(u, v) for u, v in G.edges() if v in nx.shortest_path(G, 10, u)] # 节点名称映射(键为节点ID,值为地点名称) node_labels = {549: "车站A", 10: "广场B", 123: "商场C"} # 创建1行2列的子图窗口 fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(16, 8)) # ---------------------- 子图1:节点549的最短路径 ---------------------- # 绘制背景边(淡灰色,弱化显示) nx.draw_networkx_edges(G, nodes_pos, ax=ax1, edge_color="#cccccc", width=1) # 绘制目标路径边(红色加粗,突出显示) nx.draw_networkx_edges(G, nodes_pos, edgelist=path_edges_549, ax=ax1, edge_color="#ff3333", width=2) # 绘制节点 nx.draw_networkx_nodes(G, nodes_pos, ax=ax1, node_size=300, node_color="#6699ff") # 添加节点文本标注 nx.draw_networkx_labels(G, nodes_pos, labels=node_labels, ax=ax1, font_size=10) # 设置子图标题 ax1.set_title("从节点549出发的最短路径", fontsize=12) # ---------------------- 子图2:节点10的最短路径 ---------------------- nx.draw_networkx_edges(G, nodes_pos, ax=ax2, edge_color="#cccccc", width=1) nx.draw_networkx_edges(G, nodes_pos, edgelist=path_edges_10, ax=ax2, edge_color="#33cc33", width=2) nx.draw_networkx_nodes(G, nodes_pos, ax=ax2, node_size=300, node_color="#6699ff") nx.draw_networkx_labels(G, nodes_pos, labels=node_labels, ax=ax2, font_size=10) ax2.set_title("从节点10出发的最短路径", fontsize=12) # ---------------------- 添加全局图例 ---------------------- legend_elements = [ Line2D([0], [0], color="#cccccc", lw=1, label="非路径边"), Line2D([0], [0], color="#ff3333", lw=2, label="节点549路径边"), Line2D([0], [0], color="#33cc33", lw=2, label="节点10路径边") ] # 调整图例位置,避免遮挡子图 fig.legend(handles=legend_elements, loc="center right", bbox_to_anchor=(1.1, 0.5), fontsize=10) # 自动调整子图间距,防止元素重叠 plt.tight_layout() # 显示完整窗口 plt.show()
关键细节说明
- 子图绑定:所有
nx.draw_networkx_*函数必须指定ax参数,确保绘制到对应子图,这是解决子图不显示问题的核心。 - 节点标注:通过
nx.draw_networkx_labels传入自定义labels字典,即可将节点ID替换为地点名称;若只需标注部分节点,修改字典保留目标节点即可。 - 图例制作:NetworkX绘图函数不直接生成图例,需用
Line2D手动创建图例元素,再通过fig.legend添加全局图例(也可给每个子图单独添加ax.legend)。 - 布局优化:
plt.tight_layout()自动调整子图间距,避免标题、标注重叠;图例位置可通过bbox_to_anchor参数灵活调整。
内容的提问来源于stack exchange,提问作者AliStonks
相关产品推荐
相关产品推荐

