如何在Plotly Dash的networkx图中单独设置各节点大小
解决方案
你之前的自定义节点大小不生效,核心是两个写法错误:
- Plotly的
go.Scatter标记大小参数marker.size原生支持传入与节点数量等长的数值列表,不需要循环逐节点赋值,你之前写的循环每次都会覆盖整个size参数,最终只会保留最后一个节点的数值 - 你注释掉了自定义分数列表的读取代码,且没有保证传入的大小列表顺序和图中节点顺序完全对应,会出现大小和节点错位的问题
修正后代码
只需要修改节点遍历、节点标记配置两个部分即可,和你之前matplotlib版本用自定义分数设置大小的逻辑完全对齐:
import itertools import networkx import numpy as np import plotly.graph_objects as go vertices = df_final.columns.values.tolist() edges = [((u,v),df_final[u].corr(df_final[v])) for u,v in itertools.combinations(vertices, 2)] edges = [(u,v,{'weight': abs(c)}) for (u,v),c in edges if abs(c) >= 0.5] G = networkx.Graph() G.add_edges_from(edges) # 提前做分数-节点映射,避免顺序错位 # 如果F_imp表行索引就是特征/节点名,可直接用 score_map = F_imp['Score'].to_dict() score_map = dict(zip(F_imp['feature_name'], F_imp['Score'])) pos = networkx.shell_layout(G) # 生成边轨迹 edge_x = [] edge_y = [] for edge in G.edges(): x0, y0 = pos[edge[0]] x1, y1 = pos[edge[1]] edge_x.extend([x0, x1, None]) edge_y.extend([y0, y1, None]) edge_trace = go.Scatter( x=edge_x, y=edge_y, line=dict(color='black', width=1), hoverinfo='none', showlegend=False, mode='lines') # 生成节点轨迹,同步收集每个节点对应的大小值 node_x = [] node_y = [] text = [] node_size = [] # 如果要按节点度设置大小,替换成下面这行获取度映射即可 # degree_map = dict(G.degree()) for node in G.nodes(): x, y = pos[node] node_x.append(x) node_y.append(y) text.append(node) # 取当前节点对应的自定义分数,做缩放适配Plotly的像素单位(不需要像matplotlib那样乘10000,按视觉效果调系数即可) node_size.append(score_map[node] * 50) # 按度设置大小就用下面这行 # node_size.append(degree_map[node] * 10) node_trace = go.Scatter( x=node_x, y=node_y, text=text, mode='markers+text', showlegend=False, hoverinfo='text', marker=dict( color='pink', size=node_size, # 直接传入收集好的大小列表,自动给每个节点分配对应尺寸 line=dict(color='black', width=1))) # 布局配置 layout = dict(plot_bgcolor='white', paper_bgcolor='white', margin=dict(t=10, b=10, l=10, r=10, pad=0), xaxis=dict(linecolor='black', showgrid=False, showticklabels=False, mirror=True), yaxis=dict(linecolor='black', showgrid=False, showticklabels=False, mirror=True)) fig = go.Figure(data=[edge_trace, node_trace], layout=layout) fig.show()
注意事项
- 如果
F_imp表的行索引是数字,需要把zip(F_imp['feature_name'], F_imp['Score'])里的feature_name替换成表中存储节点名称(和df_final列名完全一致)的实际列名,保证能正确匹配到每个节点的分数 - 大小的缩放系数可以根据实际视觉效果调整,Plotly的marker大小单位是像素,数值过大会导致节点重叠
- 如果需要实现节点颜色差异化,逻辑和大小完全一致,给
marker.color传入等长的颜色/数值列表即可
内容的提问来源于stack exchange,提问作者Sky_7
相关产品推荐
相关产品推荐

