CF84 CF84 - 1 month ago 14
Python Question

Python: edge length distribution of a regular network

I am working with an

NxN
regular network and I want to plot its edge length distribution.

This is how I generate the network:

import networkx as nx
import matplotlib.pyplot as plt
N=30 #This can be changed
G=nx.grid_2d_graph(N,N)
pos = dict( (n, n) for n in G.nodes() )
labels = dict( ((i, j), i + (N-1-j) * N ) for i, j in G.nodes() )
nx.relabel_nodes(G,labels,False)
inds=labels.keys()
vals=labels.values()
inds.sort()
vals.sort()
pos2=dict(zip(vals,inds))
nx.draw_networkx(G, pos=pos2, with_labels=False, node_size = 15)


This is how I compute the edge length distribution:

def plot_edge_length_distribution(): #Euclidean distances from all nodes
lengths={}
for node in G.nodes():
neigh=nx.all_neighbors(G,node) #The connected neighbors of node n
for n in neigh:
lengths[node]=((pos2[n][1]-pos2[node][1])**2)+((pos2[n][0]-pos2[node][0])**2) #The square distance
items=sorted(lengths.items())
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot([k for (k,v) in items],[v/(num_edges) for (k,v) in items],'ks-')
ax.set_xscale("linear")
ax.set_yscale("linear")
plt.yticks(numpy.arange(0.94, 1.00, 0.02))
title_string=('Edge Length Distribution')
subtitle_string=('Lattice Network | '+str(N)+'x'+str(N)+' nodes')
plt.suptitle(title_string, y=0.99, fontsize=17)
plt.title(subtitle_string, fontsize=9)
plt.xlabel('Edge Length L')
plt.ylabel('p(L)')
ax.grid(True,which="both")
plt.show()
plot_edge_length_distribution()


This is what I obtain: there is something wrong as the dict
lengths
should contain only ones as values, due to the nature of the regular grid.

This is what I want: a plot telling me that length=1 has a probability p(l)=1 because the regular grid only features edges of length 1. What is wrong in my code?

Answer

It's easier and faster to iterate over the edges and compute the distance on each one:

In [1]: import networkx as nx

In [2]: from math import sqrt

In [3]: from collections import Counter

In [4]: G = nx.grid_2d_graph(100,100)

In [5]: d = Counter(sqrt((x-a)**2 + (y-b)**2) for (x,y),(a,b) in G.edges())

In [6]: print(d)
Counter({1.0: 19800})