1

For a graph in networkx, I have made a layout to draw a network graph using code below:

data = pd.read_csv('data\\email-dept3.csv')
edges = [edge for edge in zip(data['source'],data['target'])]
print(len(edges))
G = nx.Graph()
G.add_edges_from(edges)

node_pos = nx.kamada_kawai_layout(G)

#I want to get the edge length as one attributes, but I don't know how to code this function
edge_length = calculate_edge_length()

nx.draw_networkx_nodes(G,node_pos,**options)#draw nodes
[nx.draw_networkx_edges(G,node_pos,edgelist=[key],alpha=np.amin([1,value*100]),width=2) for key,value in cent.items()] 

plt.show()

And the result is:

the shown network graph

What I want to do is get the every edge's length in this graph. Because after layout, every node has a position in screen, and the edge has its length according to its two nodes' position. But in networkx's API, I can't find the method to get the edge's length. And I also don't know how to calculate this value.

If you need more information, please contact me.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103
happy
  • 67
  • 7
  • I think your terminology is still confused. A graph is an abstract model consisting of vertices connected by edges. A plot is pixels on a screen or ink on paper. – ravenspoint Sep 04 '22 at 16:39
  • It’s my fault. I know. Thanks for reminding. – happy Sep 04 '22 at 16:45
  • So, now my question is: why do you care how long the line representing an edge might be? It is usually of no significance, other than to make the plot more or less comprehensible. – ravenspoint Sep 04 '22 at 16:46
  • Sure. I’m trying to make the graph with too many lines clearer. Because with so many nodes and lines, the plot is messy. And I am trying all kinds of methods to adjust the transparency of edges. The length of line is one of my consideration. – happy Sep 04 '22 at 16:50
  • Or maybe in this aspect, do you have some advice or insights? – happy Sep 04 '22 at 16:55
  • 1
    I would say that the decision on whether to make a line transparent should depend on the significance of the edge that the line is representing, not on the length of the line that the layout algorithm happened to choose for it. Layout algorithms, in general, are very obscure and involve a lot of randomness. – ravenspoint Sep 04 '22 at 16:56
  • Yes, I think you are right. My consideration is when length is longer, the occlusion it makes will be much more. So I assign higher importance to short lines, maybe this thinking can not work and lack of logic. – happy Sep 04 '22 at 17:05
  • Seems like a reasonable thing to try, at least just for the sake of experimentation. It’s easy to implement, so my answer is below. – Stuart Berg Sep 07 '22 at 20:36

1 Answers1

1

I am trying all kinds of methods to adjust the transparency of edges. The length of line is one of my consideration.

Interesting idea! Seems like a worthwhile experiment; I'll let you decide if it works well or not. :-)

But in networkx's API, I can't find the method to get the edge's length

I think you have to compute them yourself. Fortunately, that's not too hard. Here's an example.

import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (10,10)

def example_graph():
    """
    Return the classic Karate Club network, but give text labels to the nodes.
    """
    labels = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJZKLMNOPQRSTUVWXYZ'
    kg = nx.karate_club_graph()
    edges = [(labels[i], labels[j]) for i,j in kg.edges()]
    G = nx.Graph()
    G.add_edges_from(edges)
    return G

# Test network
G = example_graph()

# Determine layout node positions
node_pos = nx.kamada_kawai_layout(G)

# Determine edge distances (from the node positions)
node_pos_df = pd.DataFrame(node_pos.values(), columns=['x', 'y'], index=node_pos.keys())
node_pos_df = node_pos_df.rename_axis('label').sort_index()
edges = np.array(G.edges())
u_pos = node_pos_df.loc[edges[:, 0]].values
v_pos = node_pos_df.loc[edges[:, 1]].values
distances = np.linalg.norm(u_pos - v_pos, axis=1)

## Optional: Add the distances as edge attributes
#edge_distances = {(u,v): d for (u,v), d in zip(G.edges(), distances)}
#nx.set_edge_attributes(G, edge_distances, "layout_distance")

# Compute alpha: Set 0.15 as minimum alpha, 1.0 as maximum alpha
d_min, d_max = distances.min(), distances.max()
alphas = 1.0 - 0.85 * (distances - d_min) / (d_max - d_min)

# Draw graph
nx.draw_networkx_nodes(G, node_pos)
nx.draw_networkx_edges(G, node_pos, edgelist=G.edges(), alpha=alphas, width=2)

plt.show()

enter image description here

Stuart Berg
  • 17,026
  • 12
  • 67
  • 99
  • 1
    Yeah! Thank you for your code! It's very useful to me. But for your anwser `I'll let you decide if it works well or not. :-)` , it's only my experiment and I'm not sure if it works. Maybe a little, maybe just for specific dataset. :-( – happy Sep 10 '22 at 14:41