NetworkX三分层无向网络节点分析及Bokeh绘图参数配置咨询
三分层无向网络分析与Bokeh可视化配置方案
一、NetworkX核心分析操作
1. 各层连通性最强节点(度排序)
先通过节点标识区分三层(假设左层节点前缀为dFac-、中间层为mFac-、右层为vcFac-),再计算每个节点的度并按降序排序:
import networkx as nx # 提取各层节点 left_layer = [n for n in G.nodes if n.startswith('dFac-')] middle_layer = [n for n in G.nodes if n.startswith('mFac-')] right_layer = [n for n in G.nodes if n.startswith('vcFac-')] # 计算度并排序 left_sorted = sorted(G.degree(left_layer), key=lambda x: x[1], reverse=True) middle_sorted = sorted(G.degree(middle_layer), key=lambda x: x[1], reverse=True) right_sorted = sorted(G.degree(right_layer), key=lambda x: x[1], reverse=True) # 输出左层Top5示例 print("左层连通性Top5节点:", left_sorted[:5])
2. 中间层节点与左/右层连接频次统计
遍历中间层节点,筛选其左/右层邻居并统计数量:
import pandas as pd middle_left_counts = {} middle_right_counts = {} for node in middle_layer: # 统计与左层的连接数 left_neighbors = [n for n in G.neighbors(node) if n.startswith('dFac-')] middle_left_counts[node] = len(left_neighbors) # 统计与右层的连接数 right_neighbors = [n for n in G.neighbors(node) if n.startswith('vcFac-')] middle_right_counts[node] = len(right_neighbors) # 转换为DataFrame方便查看 conn_stats = pd.DataFrame({ '中间层节点': middle_layer, '与左层连接数': [middle_left_counts[n] for n in middle_layer], '与右层连接数': [middle_right_counts[n] for n in middle_layer] }) print(conn_stats.head())
3. 节点大小与边宽度的频次映射
节点大小基于节点的度(连接频次),边宽度基于数据集里的Edge-weight:
# 先将数据集的边权重导入NetworkX图 for idx, row in df.iterrows(): u, v = row['Edge-tuple'] G.add_edge(u, v, weight=row['Edge-weight']) # 节点大小:度乘以缩放因子(可根据可视化效果调整) node_sizes = [G.degree(n) * 20 for n in G.nodes] # 边宽度:权重乘以缩放因子 edge_widths = [G[u][v]['weight'] * 0.5 for u, v in G.edges]
二、Bokeh可视化配置(含边权重与节点大小)
步骤1:准备可视化数据源
用分层布局固定节点位置,整理节点和边的坐标、大小/宽度数据:
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource, HoverTool, LabelSet # 给节点添加层属性,用于分层布局 for n in G.nodes: if n.startswith('dFac-'): G.nodes[n]['layer'] = 0 elif n.startswith('mFac-'): G.nodes[n]['layer'] = 1 else: G.nodes[n]['layer'] = 2 # 生成分层布局坐标 pos = nx.multipartite_layout(G, subset_key='layer') # 整理节点数据 node_data = { 'x': [pos[n][0] for n in G.nodes], 'y': [pos[n][1] for n in G.nodes], 'label': list(G.nodes), 'size': node_sizes } node_source = ColumnDataSource(node_data) # 整理边数据 edge_data = { 'xs': [[pos[u][0], pos[v][0]] for u, v in G.edges], 'ys': [[pos[u][1], pos[v][1]] for u, v in G.edges], 'width': edge_widths } edge_source = ColumnDataSource(edge_data)
步骤2:绘制交互式网络图
# 创建画布 p = figure( title="三分层无向网络可视化", tools="pan,wheel_zoom,box_zoom,reset", x_axis_type=None, y_axis_type=None, x_axis_label='', y_axis_label='' ) # 绘制边 p.multi_line('xs', 'ys', source=edge_source, line_width='width', line_color='#888888') # 绘制节点 nodes = p.circle('x', 'y', source=node_source, size='size', color='#4287f5', alpha=0.8) # 添加悬停提示 hover = HoverTool(renderers=[nodes]) hover.tooltips = [ ("节点", "@label"), ("连接频次", "@size{int}/20") # 反向计算原始度 ] p.add_tools(hover) # 添加节点标签(可选) labels = LabelSet( x='x', y='y', text='label', source=node_source, text_font_size='8pt', x_offset=5, y_offset=5 ) p.add_layout(labels) # 展示图形 show(p)
关键注意点
- 分层布局
multipartite_layout会自动将同层节点对齐在同一水平线,比弹簧布局更适合分层网络场景。 - 节点大小和边宽度的缩放因子(如
20、0.5)需根据网络规模调整,避免节点重叠或边显示异常。 - 若需直接从数据集构建图,可跳过原有图的导入,直接用
G = nx.Graph()后遍历数据集添加带权重的边。
内容的提问来源于stack exchange,提问作者Rys
相关产品推荐
相关产品推荐

