如何基于多个邻接矩阵绘制树形结构图?
基于多层邻接矩阵绘制树形图的实现方案
核心思路
先从整理好的DataFrame中提取节点间的连接关系(边列表),再用可视化库将其渲染为层次化的树形结构。邻接矩阵中大于0的数值代表父节点到子节点存在连接,该数值可作为连接的权重(比如控制边的粗细)。
步骤1:提取边列表
遍历三个DataFrame,把所有父节点→子节点的关系(含权重)整理成统一的列表:
import pandas as pd # 复用已有的DataFrame构建代码 a = [[2, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 1, 0, 0, 1]] b = [[2, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 3, 0], [1, 0, 0, 0, 0, 0, 1]] c = [[2, 0, 0, 0, 0, 0, 0, 0, 0], [1, 2, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 2, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1, 0, 0], [0, 0, 3, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0]] data_a = pd.DataFrame(a) data_a.index = ['0a','0b','0c'] data_a.columns = ['1a','1b','1c','1d','1e'] data_b = pd.DataFrame(b) data_b.index = data_a.columns data_b.columns = ['2a','2b','2c','2d','2e','2f','2g'] data_c = pd.DataFrame(c) data_c.index = data_b.columns data_c.columns = ['3a','3b','3c','3d','3e','3f','3g','3h','3i'] # 提取边列表:格式为 (父节点, 子节点, 权重) edges = [] # 处理第一层到第二层的连接 for parent in data_a.index: for child in data_a.columns: weight = data_a.loc[parent, child] if weight > 0: edges.append( (parent, child, weight) ) # 处理第二层到第三层的连接 for parent in data_b.index: for child in data_b.columns: weight = data_b.loc[parent, child] if weight > 0: edges.append( (parent, child, weight) ) # 处理第三层到第四层的连接 for parent in data_c.index: for child in data_c.columns: weight = data_c.loc[parent, child] if weight > 0: edges.append( (parent, child, weight) )
步骤2:可视化实现
方案1:静态层次树形图(NetworkX + Matplotlib)
适合快速生成静态图,清晰展示层级结构:
import networkx as nx import matplotlib.pyplot as plt # 创建无向图(严格树形结构也可用DiGraph) G = nx.Graph() # 添加带权重的边 for u, v, w in edges: G.add_edge(u, v, weight=w) # 手动指定节点层级:根据节点名称前缀(0/1/2/3)划分 for node in G.nodes(): G.nodes[node]['layer'] = int(node[0]) # 使用层次布局 pos = nx.multipartite_layout(G, subset_key='layer') # 绘制节点 nx.draw_networkx_nodes(G, pos, node_size=1500, node_color='lightblue') # 绘制边:根据权重调整线宽 edge_width = [G[u][v]['weight']*2 for u,v in G.edges()] nx.draw_networkx_edges(G, pos, width=edge_width, edge_color='gray') # 绘制节点标签 nx.draw_networkx_labels(G, pos, font_size=10, font_weight='bold') # 绘制边权重标签 nx.draw_networkx_edge_labels(G, pos, edge_labels={(u,v):w for u,v,w in edges}) plt.axis('off') plt.tight_layout() plt.show()
方案2:交互式树形图(PyVis)
适合需要交互查看(缩放、拖拽、hover显示信息)的场景:
from pyvis.network import Network # 创建交互式有向网络对象,启用层次布局 net = Network(directed=True, layout=True, hierarchical=True) # 设置布局方向为从上到下 net.set_options(""" { "layout": { "hierarchical": { "direction": "UD", "sortMethod": "directed" } } } """) # 添加节点和带权重的边 for u, v, w in edges: net.add_node(u, label=u) net.add_node(v, label=v) net.add_edge(u, v, value=w, title=f"权重: {w}") # 生成HTML文件,打开即可查看交互式图 net.write_html("tree_visualization.html")
说明
- 邻接矩阵中的非0值作为边的权重,可通过边的粗细或标签体现;
- 利用节点名称前缀划分层级,确保树形结构的层级逻辑清晰;
- PyVis生成的HTML支持拖拽节点、缩放视图,适合复杂结构的细节查看。
内容的提问来源于stack exchange,提问作者Himan
相关产品推荐
相关产品推荐

