Networkx giving the wrong degree of nodes

Viewed 629

Networkx seems to be giving the wrong degree, it seems to be giving me double of what I would expect. I tested this in the following manner:

for i in G.nodes:
    print(i, G.degree(i), G.edges(i))

This gives an output:

326171990 4 [(326171990, 915446299), (326171990, 911571535)]
911571527 2 [(911571527, 911571535)]
911571535 6 [(911571535, 326171990), (911571535, 911571527), (911571535, 6821895165)]
915446298 4 [(915446298, 915446299), (915446298, 915446302)]
915446299 4 [(915446299, 915446298), (915446299, 326171990)]

As you can see it seems to give double the degree it should be. This is for a multigraph with many nodes, the multigraph was converted from a MultiDiGraph created using osmnx library. One this I have discovered after further inspection is that edges that used to be directed in one direction are accounted for correctly in the degree of the node. Osmnx represents two way roads as two edges one in each direction, is possible that this is the cause, if so why doesn't the edge appear to be listed twice. Any assistance with this issue would be appreciated.

2 Answers

For reference, the answer here is to use OSMnx's get_undirected function to convert from MultiDiGraph to MultiGraph. This handles the quirks of converting from a directed graph of road centerline edges to an undirected graph where a single edge represents a single physical road segment, including ensuring that parallel edges are maintained if their geometries differ. This function is the best bet anytime you want to get an undirected street network representation with OSMnx.

This could be because your graph is directed. The degree of a node that has 4 edges is 4, but G.edges(node) will only return the edges that originate from that node, not the ones that point to it.

You can access the edges pointing to the node using G.in_edges(node)

Example with directed graph H vs undirected graph G:

df = pd.DataFrame({a:np.random.randint(0,10,10) for a in 'ab'})
df 

    a   b
0   3   1
1   5   8
2   0   3
3   4   0
4   3   7
5   9   3
6   3   2
7   4   9
8   6   1
9   2   4

G = nx.from_pandas_edgelist(df, source='a', target='b')
H = nx.from_pandas_edgelist(df, source='a', target='b', create_using =nx.DiGraph())
pos = nx.spring_layout(G)

plt.subplot(121)
nx.draw_networkx(G, pos=pos)
plt.subplot(122)
nx.draw_networkx(H, pos=pos)

enter image description here

for i in G.nodes:
    print(i, G.degree(i), G.edges(i))

3 5 [(3, 1), (3, 0), (3, 7), (3, 9), (3, 2)]
1 2 [(1, 3), (1, 6)]
5 1 [(5, 8)]
8 1 [(8, 5)]
0 2 [(0, 3), (0, 4)]
4 3 [(4, 0), (4, 9), (4, 2)]
7 1 [(7, 3)]
9 2 [(9, 3), (9, 4)]
2 2 [(2, 3), (2, 4)]
6 1 [(6, 1)]


for i in H.nodes:
    print(i, H.degree(i), H.edges(i), H.in_edges(i))

3 5 [(3, 1), (3, 7), (3, 2)] [(0, 3), (9, 3)]
1 2 [] [(3, 1), (6, 1)]
5 1 [(5, 8)] []
8 1 [] [(5, 8)]
0 2 [(0, 3)] [(4, 0)]
4 3 [(4, 0), (4, 9)] [(2, 4)]
7 1 [] [(3, 7)]
9 2 [(9, 3)] [(4, 9)]
2 2 [(2, 4)] [(3, 2)]
6 1 [(6, 1)] []
Related