You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将NetworkX构建的2D网络图转换为Python中的交互式3D网络图?

如何将NetworkX构建的2D网络图转换为Python中的交互式3D网络图?

嘿,我来帮你搞定这个问题!把2D网络图转成3D交互式的确实能让复杂的关系更清晰,尤其是节点多的时候。NetworkX本身不直接支持3D渲染,但我们可以结合它的图结构+3D布局算法,再用Plotly这样的可视化库来生成交互式3D图,操作起来超方便~

下面是一套完整的可运行方案,完全沿用你原来的节点颜色逻辑,同时生成可旋转、缩放的交互式3D图:

第一步:准备依赖库

如果还没安装所需的库,先运行这个命令:

pip install networkx pandas plotly matplotlib

第二步:完整实现代码

import pandas as pd
import networkx as nx
import plotly.graph_objects as go
import matplotlib as mpl

# 1. 加载你的网络数据(替换成你本地的links_filtered.csv文件路径)
links_data = pd.read_csv("你的本地links_filtered.csv文件路径")
G = nx.from_pandas_edgelist(links_data, 'var1', 'var2')

# 2. 沿用你原来的节点颜色映射逻辑(按Category给节点分类着色)
cmap = mpl.colormaps['Set3'].colors  # 12种颜色对应11个类别
cat_colors = dict(zip(links_data['Category'].unique(), cmap))
node_colors = (links_data
               .drop_duplicates('var1').set_index('var1')['Category']
               .map(cat_colors)
               .reindex(G.nodes)
)
# 将Matplotlib的RGB颜色转成Plotly兼容的十六进制格式
node_colors_hex = [mpl.colors.to_hex(color) for color in node_colors]

# 3. 计算3D空间的节点布局(用NetworkX的弹簧布局算法,指定3维)
pos = nx.spring_layout(G, dim=3, seed=42)  # seed固定布局,保证每次运行结果一致

# 4. 提取节点的3D坐标数据
node_x = [pos[node][0] for node in G.nodes()]
node_y = [pos[node][1] for node in G.nodes()]
node_z = [pos[node][2] for node in G.nodes()]

# 5. 提取边的3D坐标数据(Plotly需要用None分隔不同的边)
edge_x = []
edge_y = []
edge_z = []
for edge in G.edges():
    x0, y0, z0 = pos[edge[0]]
    x1, y1, z1 = pos[edge[1]]
    edge_x.extend([x0, x1, None])
    edge_y.extend([y0, y1, None])
    edge_z.extend([z0, z1, None])

# 6. 构建交互式3D图
fig = go.Figure()

# 先绘制边(放在节点下方,避免遮挡节点)
fig.add_trace(go.Scatter3d(
    x=edge_x, y=edge_y, z=edge_z,
    mode='lines',
    line=dict(color='black', width=1),
    hoverinfo='none'
))

# 再绘制节点(带标签和分类颜色)
fig.add_trace(go.Scatter3d(
    x=node_x, y=node_y, z=node_z,
    mode='markers+text',
    marker=dict(
        size=5,
        color=node_colors_hex,
        line=dict(color='white', width=0.5)  # 给节点加白色边框,提升辨识度
    ),
    text=[node for node in G.nodes()],
    textposition="top center",
    textfont=dict(size=8),
    hoverinfo='text'  # 鼠标悬停显示节点名称
))

# 调整布局,让交互体验更好
fig.update_layout(
    title='交互式3D网络图',
    showlegend=False,
    scene=dict(
        xaxis=dict(showgrid=False, showticklabels=False, title=''),
        yaxis=dict(showgrid=False, showticklabels=False, title=''),
        zaxis=dict(showgrid=False, showticklabels=False, title=''),
        camera=dict(eye=dict(x=1.5, y=1.5, z=0.8))  # 初始视角参数,可按需调整
    ),
    margin=dict(l=0, r=0, b=0, t=40)
)

# 显示交互式图(会在浏览器或Jupyter Notebook中打开)
fig.show()

关键细节说明:

  1. 3D布局算法:用nx.spring_layout(G, dim=3)让NetworkX在3D空间中自动布局节点,尽量减少边的交叉,加seed=42是为了固定布局结果,方便你反复调试。
  2. 颜色兼容:把你原来用Matplotlib定义的分类颜色转成Plotly支持的十六进制格式,完美保留你原来的着色逻辑。
  3. 交互特性:生成的图支持:
    • 鼠标拖拽旋转视角,找到最清晰的观察角度
    • 滚轮缩放图的大小
    • 鼠标悬停节点时显示节点名称
  4. 自定义空间:如果需要调整节点大小、标签字体、初始视角等,直接修改代码里对应的参数就行,比如marker=dict(size=5)改节点大小,textfont=dict(size=8)改标签字体。

其他可选方案(按需选择):

如果你需要更偏向桌面端的3D渲染效果(比如支持更多光影效果),可以尝试用MayaviPyVista库,但这两个库的安装和使用门槛稍高,需要依赖VTK环境。对于大多数场景,Plotly的方案已经足够轻量且好用了~

备注:内容来源于stack exchange,提问作者ViSa

火山引擎 最新活动