Plotly绘制网络图如何按簇筛选Top节点并显示常驻标签
Plotly网络图按簇筛选Top节点并显示常驻标签实现方案
核心筛选逻辑修正
全局按节点尺寸排序取Top的逻辑没有做簇级去重,才会出现同簇多节点占用名额的问题,正确筛选流程如下:
- 先将所有节点按所属网络簇做分组
- 每个簇内部按节点尺寸降序排序,仅保留每个簇尺寸最大的节点(同簇其他节点直接排除入选资格)
- 将所有簇选出的代表节点按尺寸降序排序,取前N个目标节点,即可得到符合规则的结果
对应实现代码(以pandas存储节点数据为例):
import pandas as pd # 替换为你的真实节点数据,字段分别为节点ID、节点尺寸、所属簇ID nodes_df = pd.DataFrame([ {"node_id": 1, "size": 100, "cluster": "A"}, {"node_id": 4, "size": 90, "cluster": "A"}, {"node_id": 2, "size": 80, "cluster": "B"}, {"node_id": 3, "size": 70, "cluster": "C"}, ]) # 按簇分组取每个簇尺寸最大的节点 cluster_top = nodes_df.sort_values("size", ascending=False)\ .groupby("cluster", as_index=False)\ .first() # 跨簇排序取前3个目标节点,运行结果为[1,2,3],符合预期 selected_nodes = cluster_top.sort_values("size", ascending=False)\ .head(3)["node_id"].tolist()
如果需要每个簇入选k个节点,把分组后的first()替换为head(k)即可,逻辑通用。
常驻标签配置
不需要额外绘制单独的标签图层,直接利用Plotly散点图的文本属性即可实现「选中节点常驻显示标签、其余节点仅悬浮显示提示」的效果:
- 给节点数据集新增标签字段,默认赋值为空字符串
- 仅给筛选出的目标节点填充要显示的标签内容
- 绘图时同时开启标记和文本模式,所有节点保留悬浮提示配置
对应绘图代码:
import plotly.graph_objects as go # 提前通过网络布局算法(如networkx的spring_layout)生成所有节点的x、y坐标,以及边的坐标 # edges_x、edges_y为边的折线坐标,格式为[源点x, 汇点x, None, 源点x2, 汇点x2, None...] nodes_df["show_label"] = "" nodes_df.loc[nodes_df["node_id"].isin(selected_nodes), "show_label"] = nodes_df["node_id"].astype(str) fig = go.Figure() # 绘制网络边 fig.add_trace(go.Scatter( x=edges_x, y=edges_y, mode="lines", line=dict(width=1, color="#ccc"), hoverinfo="none" )) # 绘制节点 fig.add_trace(go.Scatter( x=nodes_df["x"], y=nodes_df["y"], mode="markers+text", marker=dict( # 节点尺寸做适当缩放适配画布 size=nodes_df["size"] / 10, # 按簇分配节点颜色 color=nodes_df["cluster"].astype("category").cat.codes, colorscale="Set2", line=dict(width=1, color="#fff") ), # 仅选中节点有文本内容,其余节点为空不会显示标签 text=nodes_df["show_label"], textposition="top center", textfont=dict(size=12, color="#333"), # 所有节点保留悬浮提示 hovertext=nodes_df.apply(lambda x: f"节点{x['node_id']}<br>尺寸:{x['size']}<br>所属簇:{x['cluster']}", axis=1), hoverinfo="text" )) fig.update_layout( showlegend=False, xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False) ) fig.show()
配置完成后运行代码,即可实现节点1、2、3常驻显示标签,节点4等其余节点仅在鼠标悬浮时展示信息的效果,不会出现同簇多节点占用入选名额的问题。
内容的提问来源于stack exchange,提问作者nphaibk
相关产品推荐
相关产品推荐

