Networkx DiGraph与Matplotlib绘图方向调整问题求助
问题根源
节点会垂直乱延伸,核心问题出在y坐标的计算逻辑上:你现在用len(heights)作为新节点的y值,每加一个节点这个数值就涨一次,自然会把图拉得越来越长。
修正方案
要实现「节点仅水平扩展,'0'在左侧中间」的效果,得按节点的高度(x轴方向)分组,同一高度的节点在垂直方向均匀排布且整体居中。下面是改好的代码:
def draw(self): # 先创建图并添加所有边,确保所有节点都被纳入 G = nx.DiGraph() for tx in self.transactions.values(): for parent_txid in tx.parent_txids: G.add_edge(tx.txid, parent_txid) # 先计算所有节点的高度(对应x坐标) heights = {} for tx in self.transactions.values(): if tx.txid == '0': heights[tx.txid] = 0 else: max_parent_height = max(heights[p_txid] for p_txid in tx.parent_txids) heights[tx.txid] = max_parent_height + 1 # 按高度(x值)把节点分组 nodes_by_x = {} for txid in G.nodes(): x_val = heights[txid] if x_val not in nodes_by_x: nodes_by_x[x_val] = [] nodes_by_x[x_val].append(txid) # 计算每个节点的位置:x是高度,y让同层节点垂直居中 pos = {} for x_val, txids in nodes_by_x.items(): node_count = len(txids) # 给同层节点分配y值,比如1个节点y=0,2个节点y=-0.5/0.5,3个节点y=-1/0/1 y_coords = [-(node_count-1)/2 + i for i in range(node_count)] for idx, txid in enumerate(txids): pos[txid] = (x_val, y_coords[idx]) # 设置节点颜色(必须按G.nodes()的顺序来,避免颜色对应错) node_colors = [] for txid in G.nodes(): tx = self.transactions[txid] if tx.txid == '1': node_colors.append('orange') # 橙色标记指定节点 elif tx.txid == '0' and self.current_batch == 0: node_colors.append('grey') # 初始节点设为灰色 elif tx in self.tips: node_colors.append('grey') # tips节点设为灰色 else: node_colors.append('blue') # 其他节点蓝色 # 绘制图形 plt.figure(figsize=(10, 5)) nx.draw(G, pos=pos, with_labels=True, node_color=node_colors, node_size=1000, node_shape='s') # 根据实际节点的y值自动调整坐标轴范围 all_y_vals = [y for x, y in pos.values()] plt.ylim(min(all_y_vals)-0.5, max(all_y_vals)+0.5) plt.xlim(-0.5, max(heights.values()) + 0.5) plt.show()
关键改动说明
- 先建图再处理节点:先把所有边加进图里,确保不会漏掉任何节点
- 按高度分组算y坐标:同一水平层的节点垂直方向均匀分布,不会无限制往下/往上拉
- 颜色对应节点顺序:跟着图里的节点顺序设置颜色,避免出现“节点颜色对不上”的问题
- 动态调坐标轴:根据实际节点位置自动调整范围,不用手动瞎试参数
这样改完后,节点会沿着x轴水平扩展,'0'节点稳稳站在左侧垂直居中的位置,不会再乱垂直延伸了。
内容的提问来源于stack exchange,提问作者MKM
相关产品推荐
相关产品推荐

