如何在Python中翻转igraph树,解决树形图倒置问题?
解决igraph树形图倒置问题:让"HoPE"节点显示在顶部
问题
使用Python的igraph构建树形图时,顶层节点"HoPE"显示在底部,树形结构倒置,需要调整为从上到下展开的样式。
解决方案
以下三种方法都可以解决该问题,优先推荐方法1,操作最简便:
方法1:反转Plotly的Y轴
直接在Plotly的布局配置中反转Y轴方向,无需修改坐标数据。
修改代码中的fig.update_layout部分,在yaxis配置里添加autorange="reversed":
fig.update_layout( showlegend=True, hovermode="closest", margin=dict(b=0, l=0, r=0, t=0), xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, autorange="reversed") )
方法2:手动翻转坐标值
对所有节点和边的Y坐标取反,实现方向翻转。
在获取节点和边的坐标后添加以下代码:
# 翻转所有节点的Y坐标 node_y = [-y for y in node_y] # 翻转所有边的Y坐标 edge_y = [-y for y in edge_y]
方法3:指定igraph布局根节点并调整方向
在生成Reingold-Tilford布局时指定根节点为"HoPE",再翻转坐标:
# 找到HoPE节点的索引 root_idx = g.vs.find("HoPE").index # 以HoPE为根生成布局 layt = g.layout("rt", root=root_idx) # 后续步骤中翻转Y坐标 node_y = [-y for y in node_y] edge_y = [-y for y in edge_y]
修改后的完整代码(以方法1为例)
import igraph import plotly.graph_objects as go # Create an empty graph g = igraph.Graph(directed=True) # Add vertices with labels g.add_vertex("HoPE") # add FA node for a in ['FA']: fa_node = f"HoPE_{a}" g.add_vertex(fa_node) g.add_edge('HoPE', fa_node) # add exp node for b in ['exp']: exp_node = f"HoPE_{a}_{b}" g.add_vertex(exp_node) g.add_edge(fa_node, exp_node) # add TX node for c in ['TX']: tx_node = f"HoPE_{a}_{b}_{c}" g.add_vertex(tx_node) g.add_edge(exp_node, tx_node) # Add C nodes for condition in ["C1", "C2", "C3", "C4"]: c_nodes = f"HoPE_FA_exp_TX_{condition}" g.add_vertex(c_nodes) g.add_edge(tx_node, c_nodes) # Add TR nodes for i in range(1, 4): # TR1, TR2, TR3 tr_node = f"HoPE_{a}_{b}_{c}_{condition}_TR{i}" g.add_vertex(tr_node) g.add_edge(c_nodes, tr_node) # Add 5 AR nodes for each TR node for j in range(1, 6): # AR1, AR2, AR3, AR4, AR5 ar_node = f"HoPE_{a}_{b}_{c}_{condition}_TR{i}_AR{j}" g.add_vertex(ar_node) g.add_edge(tr_node, ar_node) # Convert igraph layout to Plotly format layt = g.layout("rt") # Get edge coordinates edge_x, edge_y = [], [] for edge in g.get_edgelist(): x0, y0 = layt[edge[0]] x1, y1 = layt[edge[1]] edge_x.extend([x0, x1, None]) edge_y.extend([y0, y1, None]) # Get vertex coordinates and labels node_x, node_y = zip(*[layt[vertex] for vertex in g.vs.indices]) node_labels = g.vs['name'] # Create Plotly trace for edges edge_trace = go.Scatter( x=edge_x, y=edge_y, line=dict(width=0.5, color="#888"), hoverinfo="none", mode="lines", ) # Create Plotly trace for nodes node_trace = go.Scatter( x=node_x, y=node_y, mode="markers", hoverinfo="text", marker=dict(showscale=True, colorscale="YlGnBu", size=10), text=node_labels, # Display node labels on hover ) # Create a figure and add traces fig = go.Figure(data=[edge_trace, node_trace]) # Customize layout - 添加了autorange="reversed" fig.update_layout( showlegend=True, hovermode="closest", margin=dict(b=0, l=0, r=0, t=0), xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, autorange="reversed"), ) # Show the interactive plot fig.show() print(node_labels)
内容的提问来源于stack exchange,提问作者yade acem
相关产品推荐
相关产品推荐

