如何用数组控制3D图边透明度?解决Axes3DSubplot报错并求库推荐
3D网络图实现边和节点透明度控制的解决方案
错误原因
draw_networkx_nodes是NetworkX的专属绘图函数,不能通过Matplotlib的3D轴对象(Axes3DSubplot)调用,且NetworkX原生绘图API仅针对2D场景设计,无直接支持3D节点/边绘制的方法。
方案一:基于现有依赖(Matplotlib+NetworkX)手动实现
无需额外安装库,直接用Matplotlib的3D绘图API手动绘制节点和边,支持数组控制透明度:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import networkx as nx import numpy as np def draw_graph(edges): G = nx.Graph() G.add_edges_from(edges) pos = nx.spring_layout(G, dim=3) pos_ary = np.array([pos[n] for n in G.nodes()]) node_count = len(G.nodes()) edge_count = len(G.edges()) # 生成节点、边的透明度数组(长度匹配节点/边数量) node_alphas = np.linspace(0.1, 1, node_count) edge_alphas = np.linspace(0.1, 1, edge_count) fig = plt.figure(figsize=(20,10), facecolor="w") ax = fig.add_subplot(111, projection="3d") # 绘制节点,传入透明度数组 ax.scatter( pos_ary[:, 0], pos_ary[:, 1], pos_ary[:, 2], s=200, c="b", alpha=node_alphas ) # 遍历边,逐个绘制并设置对应透明度 for idx, e in enumerate(G.edges()): node0_pos = pos[e[0]] node1_pos = pos[e[1]] xx = [node0_pos[0], node1_pos[0]] yy = [node0_pos[1], node1_pos[1]] zz = [node0_pos[2], node1_pos[2]] ax.plot3D(xx, yy, zz, color="b", alpha=edge_alphas[idx]) plt.show() edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0), (0, 5), (1, 6), (2, 7), (3, 8), (4, 9)] draw_graph(edges)
方案二:使用Plotly库(交互式3D网络图)
Plotly对3D网络图支持更友好,原生支持节点/边的独立透明度设置,且生成交互式可拖拽的图:
先安装Plotly:
pip install plotly
示例代码:
import plotly.graph_objects as go import networkx as nx import numpy as np def draw_3d_graph(edges): G = nx.Graph() G.add_edges_from(edges) pos = nx.spring_layout(G, dim=3) # 提取节点坐标 x_nodes = [pos[n][0] for n in G.nodes()] y_nodes = [pos[n][1] for n in G.nodes()] z_nodes = [pos[n][2] for n in G.nodes()] # 生成透明度数组 node_alphas = np.linspace(0.1, 1, len(G.nodes())) edge_alphas = np.linspace(0.1, 1, len(G.edges())) # 整理边的坐标数据(用None分隔不同边) x_edges = [] y_edges = [] z_edges = [] for e in G.edges(): x_edges.extend([pos[e[0]][0], pos[e[1]][0], None]) y_edges.extend([pos[e[0]][1], pos[e[1]][1], None]) z_edges.extend([pos[e[0]][2], pos[e[1]][2], None]) # 创建节点轨迹 node_trace = go.Scatter3d( x=x_nodes, y=y_nodes, z=z_nodes, mode='markers', marker=dict( size=10, color='blue', opacity=node_alphas ) ) # 创建每条边的轨迹,单独设置透明度 edge_traces = [] for idx in range(len(G.edges())): start_idx = idx * 3 edge_trace = go.Scatter3d( x=x_edges[start_idx:start_idx+2], y=y_edges[start_idx:start_idx+2], z=z_edges[start_idx:start_idx+2], mode='lines', line=dict(color='blue', width=2), opacity=edge_alphas[idx] ) edge_traces.append(edge_trace) # 组合所有轨迹并展示 fig = go.Figure(data=[node_trace] + edge_traces) fig.show() edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 0), (0, 5), (1, 6), (2, 7), (3, 8), (4, 9)] draw_3d_graph(edges)
内容的提问来源于stack exchange,提问作者networkxxxx
相关产品推荐
相关产品推荐

