我设法正确地生成了图表,但是对于以下两个不同的代码行,有一些更多的测试指出了不一致的结果:
nx.draw_circular(h,edge_color=[h.edge[i][j]['color'] for (i,j) in h.edges_iter()], width=[h.edge[i][j]['width'] for (i,j) in h.edges_iter()])
nx.draw_circular(h,edge_color=list(nx.get_edge_attributes(h,'color').values()), width=list(nx.get_edge_attributes(h,'width').values()))
第一行产生一致的输出,而第二行产生每个边缘的错误颜色/大小。
然而,在我看来,上面两行都依赖于函数调用来返回每个边缘顺序的属性。为什么会有不同的结果?
使用h[][][]
访问属性对我来说有点笨拙;是否可以通过点约定来访问它,例如edge.color for edge in h.edges()
。
或者我错过了什么?
答案 0 :(得分:43)
传递给绘图函数的边的顺序很重要。如果您未指定(使用edges关键字),您将获得G.edges()的默认顺序。最明确地给出如下参数是最安全的:
import networkx as nx
G = nx.Graph()
G.add_edge(1,2,color='r',weight=2)
G.add_edge(2,3,color='b',weight=4)
G.add_edge(3,4,color='g',weight=6)
pos = nx.circular_layout(G)
edges = G.edges()
colors = [G[u][v]['color'] for u,v in edges]
weights = [G[u][v]['weight'] for u,v in edges]
nx.draw(G, pos, edges=edges, edge_color=colors, width=weights)
这会产生如下输出:
答案 1 :(得分:7)
字典是用于NetworkX图形的基础数据结构,从Python 3.7+开始,它们maintain insertion order。
这意味着我们可以安全地使用nx.get_edge_attributes
来检索边缘属性,因为可以确保每次运行Graph.edges()
时都具有相同的边缘顺序(内部由get_edge_attributes
调用)。>
因此,在绘制时,我们可以根据edge_color
返回的结果直接设置诸如width
和get_edge_attributes
之类的属性。这是一个示例:
G = nx.Graph()
G.add_edge(0,1,color='r',weight=2)
G.add_edge(1,2,color='g',weight=4)
G.add_edge(2,3,color='b',weight=6)
G.add_edge(3,4,color='y',weight=3)
G.add_edge(4,0,color='m',weight=1)
colors = nx.get_edge_attributes(G,'color').values()
weights = nx.get_edge_attributes(G,'weight').values()
pos = nx.circular_layout(G)
nx.draw(G, pos,
edge_color=colors,
width=list(weights),
with_labels=True,
node_color='lightgreen')
答案 2 :(得分:0)
如果您想避免手动添加边缘颜色和 alphas/宽度,您可能还会发现此功能很有用:
def rgb_to_hex(rgb):
return '#%02x%02x%02x' % rgb
adjacency_matrix = np.array([[0, 0, 0.5], [1, 0, 1], [1, 0.5, 0]]))
n_graphs = 5
fig, axs = plt.subplots(1, len(n_graphs), figsize=(19,2.5))
for graph in range(n_graphs):
pos = {0: (1, 0.9), 1: (0.9, 1), 2: (1.1, 1)}
# draw DAG graph from adjacency matrix
gr = nx.from_numpy_matrix(adjacency_matrix, create_using=nx.DiGraph)
weights = nx.get_edge_attributes(gr, "weight")
# adding nodes
all_rows = range(0, adjacency_matrix.shape[0])
for n in all_rows:
gr.add_node(n)
# getting edges
edges = gr.edges()
# weight and color of edges
scaling_factor = 4 # to emphasise differences
alphas = [weights[edge] * scaling_factor for edge in edges]
colors = [rgb_to_hex(tuple(np.repeat(int(255 * (1-
weights[edge])),3))) for edge in edges]
# draw graph
nx.draw(gr,
pos,
ax=axs[graph],
edgecolors='black',
node_color='white',
node_size=2000,
labels={0: "A", 1: "B", 2: "C"},
font_weight='bold',
linewidths=2,
with_labels=True,
connectionstyle="arc3,rad=0.15",
edge_color=colors,
width=alphas)
plt.tight_layout()