如何基于邻接列表正确可视化4×14二维网格图?
问题描述
我通过程序生成了代表4×14二维网格图的邻接列表(并非所有节点都与全部邻居相连),具体如下:
list_ng2d={(0, 0): [(0, 1)], (0, 1): [(0, 2), (0, 0)], (0, 2): [(1, 2), (0, 3), (0, 1)], (0, 3): [(0, 4), (0, 2)], (0, 4): [(1, 4), (0, 5), (0, 3)], (0, 5): [(0, 6), (0, 4)], (0, 6): [(0, 7), (0, 5)], (0, 7): [(0, 8), (0, 6)], (0, 8): [(0, 9), (0, 7)], (0, 9): [(1, 9), (0, 10), (0, 8)], (0, 10): [(0, 11), (0, 9)], (0, 11): [(1, 11), (0, 12), (0, 10)], (0, 12): [(0, 13), (0, 11)], (0, 13): [(0, 12)], (1, 0): [(1, 1)], (1, 1): [(1, 2), (1, 0)], (1, 2): [(0, 2), (1, 3), (1, 1)], (1, 3): [(1, 4), (1, 2)], (1, 4): [(0, 4), (1, 5), (1, 3)], (1, 5): [(1, 6), (1, 4)], (1, 6): [(2, 6), (1, 7), (1, 5)], (1, 7): [(1, 8), (1, 6)], (1, 8): [(2, 8), (1, 9), (1, 7)], (1, 9): [(0, 9), (1, 10), (1, 8)], (1, 10): [(1, 11), (1, 9)], (1, 11): [(0, 11), (1, 12), (1, 10)], (1, 12): [(1, 13), (1, 11)], (1, 13): [(1, 12)], (2, 0): [(2, 1)], (2, 1): [(2, 2), (2, 0)], (2, 2): [(3, 2), (2, 3), (2, 1)], (2, 3): [(2, 4), (2, 2)], (2, 4): [(3, 4), (2, 5), (2, 3)], (2, 5): [(2, 6), (2, 4)], (2, 6): [(1, 6), (2, 7), (2, 5)], (2, 7): [(2, 8), (2, 6)], (2, 8): [(1, 8), (2, 9), (2, 7)], (2, 9): [(3, 9), (2, 10), (2, 8)], (2, 10): [(2, 11), (2, 9)], (2, 11): [(3, 11), (2, 12), (2, 10)], (2, 12): [(2, 13), (2, 11)], (2, 13): [(2, 12)], (3, 0): [(3, 1)], (3, 1): [(3, 2), (3, 0)], (3, 2): [(2, 2), (3, 3), (3, 1)], (3, 3): [(3, 4), (3, 2)], (3, 4): [(2, 4), (3, 5), (3, 3)], (3, 5): [(3, 6), (3, 4)], (3, 6): [(3, 7), (3, 5)], (3, 7): [(3, 8), (3, 6)], (3, 8): [(3, 9), (3, 7)], (3, 9): [(2, 9), (3, 10), (3, 8)], (3, 10): [(3, 11), (3, 9)], (3, 11): [(2, 11), (3, 12), (3, 10)], (3, 12): [(3, 13), (3, 11)], (3, 13): [(3, 12)]}
我尝试用NetworkX库绘制该图,现有代码如下:
H = nx.Graph(list_ng2d) # nx.draw(H, with_labels=True, font_weight='bold') G=nx.grid_2d_graph(N,M) # plt.figure(figsize=(6,6)) pos=dict() for node,val in list_ng2d.items(): # print(f" {node} ngbrs {val}") for ngbr in val: pos[node]=ngbr # pos = {(x,y):(y,-x) for x,y in G.nodes()} # G.remove_edges_from([(0,13),(1,13)]) # nx.draw(G, pos=nx.get_node_attributes(G, 'pos'), # node_color='lightgreen', # with_labels=True, # node_size=100) nx.relabel_nodes(G,labels,False) labels = dict(((i, j), i *M + (j)) for i, j in H.nodes()) #M=14 pos = {y:x for x,y in labels.items()} nx.draw_networkx(G, pos=pos, with_labels=True, node_size = 100) labels.items()
但绘图结果出现了邻接列表中不存在的额外边,无法得到预期的可视化效果,求正确的实现方向或思路。
解决方案
你的核心问题是误用了nx.grid_2d_graph生成的完整网格图,这个图包含所有默认的网格边,而你需要的是基于自定义邻接列表的图,所以会出现额外边。正确实现思路如下:
直接使用自定义邻接列表创建图
你已经用H = nx.Graph(list_ng2d)创建了正确的图,这一步没问题,不需要再用nx.grid_2d_graph生成新图,后者会引入多余的边。设置正确的节点网格位置
要让节点按4×14的网格排列,手动定义每个节点的绘图坐标,比如让(row, col)对应绘图坐标(col, -row)(保证行号从上到下递增时,绘图位置符合视觉习惯):pos = {(x, y): (y, -x) for x, y in H.nodes()}绘图并自定义样式
直接绘制你创建的H图,无需混用其他图对象。如果需要将节点的(row,col)格式转为序号标签,直接在绘图时传入自定义标签字典即可:import matplotlib.pyplot as plt import networkx as nx # 用自定义邻接列表创建图 H = nx.Graph(list_ng2d) # 设置网格节点位置 pos = {(x, y): (y, -x) for x, y in H.nodes()} # 自定义节点标签(将(row,col)转为序号) labels = {(i, j): i * 14 + j for i, j in H.nodes()} # 适配4×14的比例设置画布大小 plt.figure(figsize=(14, 4)) nx.draw_networkx(H, pos=pos, labels=labels, node_size=300, node_color='lightgreen') plt.show()关键注意事项
- 不要混用
nx.grid_2d_graph生成的图和自定义邻接列表的图,前者是完整网格结构,会覆盖你的自定义边 - 位置字典
pos要准确对应每个节点的网格位置,保证可视化布局符合预期 - 如需修改节点显示标签,直接在
draw_networkx的labels参数中传入字典即可,无需调用nx.relabel_nodes(除非需要修改图本身的节点名称)
- 不要混用
内容的提问来源于stack exchange,提问作者user206904
相关产品推荐
相关产品推荐

