【问题标题】:NetworkX: regular graph created from 2D numpy array yields mismatchesNetworkX:从 2D numpy 数组创建的常规图会产生不匹配
【发布时间】:2017-05-29 11:22:26
【问题描述】:

假设你有一个像这样的二维 numpy 数组(raster):

import matplotlib.pyplot as plt
import numpy as np
N=5
np.random.seed(17) #For reproducibility
A=np.random.rand(N,N)

In[1]: A
Out[1]:
array([[ 0.294665  ,  0.53058676,  0.19152079,  0.06790036,  0.78698546],
       [ 0.65633352,  0.6375209 ,  0.57560289,  0.03906292,  0.3578136 ],
       [ 0.94568319,  0.06004468,  0.8640421 ,  0.87729053,  0.05119367],
       [ 0.65241862,  0.55175137,  0.59751325,  0.48352862,  0.28298816],
       [ 0.29772572,  0.56150891,  0.39604744,  0.78870071,  0.41848439]])

绘制时如下所示:

im=plt.imshow(A,origin="upper",interpolation="nearest",cmap=plt.cm.gray_r)
plt.colorbar(im)

并且说你要创建一个二维图(一个格子网络),其中每个栅格单元对应一个节点,每个节点的大小就是单元的值:

import networkx as nx
#Turn the matrix into a dictionary with the format {(i,j):value}
dict_of_values={(i,j):A[i][j] for i in range(0,A.shape[0]) for j in range(0,A.shape[1])}

#Create lattice network of the same size as A
G = nx.grid_2d_graph(N,N)

#Make sure the nodes are plotted according to a regular grid
labels=dict(((i,j),i + (N-1-j)*N) for i, j in G.nodes())
nx.relabel_nodes(G,labels,False) #False=relabel the nodes in place
inds=labels.keys()
vals=labels.values()
inds=[(N-j-1,N-i-1) for i,j in inds]
#Create the dictionary of positions for the grid
grid_pos=dict(zip(vals,inds)) #Format: {node ID:(i,j)}

#Look up the value for each node in the matrix A
inverted_grid_pos=dict(zip(inds,vals)) #Format: {(i,j):node ID}
#The values in A for each node come from "dict_of_values"
values=[dict_of_values.get(node) for node in inverted_grid_pos]
exaggerate_values=[300*i for i in values]

#Plot the graph with the size based on the values
plt.figure()
nx.draw(G,pos=grid_pos,with_labels=True,node_size=exaggerate_values)

此脚本返回不匹配:节点的大小与二维数组中的值不匹配。事实上,我预计节点2121720 是最大的,但这不会发生。

不匹配出现在哪里?

【问题讨论】:

    标签: python arrays numpy matplotlib networkx


    【解决方案1】:

    您可以直接使用转置数组A 来获取节点大小,而不是从无序字典生成节点大小。

    import matplotlib.pyplot as plt
    import numpy as np
    import networkx as nx
    
    N=4
    np.random.seed(17) #For reproducibility
    A=np.random.choice([200,400,800], size=(N,N))
    A[3,1] = 1500
    im=plt.imshow(A,origin="upper",interpolation="nearest",cmap=plt.cm.gray_r)
    plt.colorbar(im)
    
    
    G = nx.grid_2d_graph(N,N)
    
    labels=dict(((i,j),i + (N-1-j)*N) for i, j in G.nodes())
    nx.relabel_nodes(G,labels,False) #False=relabel the nodes in place
    inds=labels.keys()
    vals=labels.values()
    inds=[(N-j-1,N-i-1) for i,j in inds]
    
    #Create the dictionary of positions for the grid
    grid_pos=dict(zip(vals,inds)) #Format: {node ID:(i,j)}
    
    
    #Plot the graph with the size based on the values
    plt.figure()
    nx.draw(G,pos=grid_pos,with_labels=True,node_size=A.T.flatten())
    
    plt.show()
    

    【讨论】:

    • 如果要为每个节点分配对应的数组值作为属性怎么办?如果你做nx.set_node_attributes(G, 'index', A.T.flatten()),你给每个节点整个扁平化数组。
    • 有意思,转换成列表有帮助吗,list(A.T.flatten()) ?
    • 不,它仅在您创建属性字典时才有效,根据 the documentation,然后您在 nx.set_node_attributes(G, 'atts', attributes) 中使用它。这将确保每个节点都获得相关属性。
    • 好吧,G.nodes() 返回一个列表有点烦人,但其他一切都需要字典。我还没有完全理解节点索引背后的结构,所以我不知道字典应该是什么样子。
    猜你喜欢
    • 2017-09-11
    • 2018-01-15
    • 2017-04-06
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2022-09-23
    • 2018-12-22
    • 1970-01-01
    相关资源
    最近更新 更多