
Adding edge weights
So far, all of the edges in this chapter have been unweighted, but the Graph class also supports weighted edges. Edge weights are handy when connections can have different strengths and when there is a way to quantify the strength of a connection; for example, how often two friends talk to each other, the volume of fluid a pipe can transport, or the number of direct flights between two cities.
The karate club network doesn't have any additional information about the strength of the edges, but there are relevant properties of those edges that can be calculated, such as the tie strength. Tie strength increases with the number of neighbors that two nodes have in common. It is motivated by the observation that closer friends tend to have more friends in common, and it can often reveal insight into the structure of a social network. The following code calculates the tie strength using the neighbors() method to find node neighbors, and Python sets to compute the number of neighbors in common:
def tie_strength(G, v, w):
# Get neighbors of nodes v and w in G
v_neighbors = set(G.neighbors(v))
w_neighbors = set(G.neighbors(w))
# Return size of the set intersection
return 1 + len(v_neighbors & w_neighbors)
Here, we've defined the tie strength as the number of common neighbors plus one. Why plus one? A weight of zero conventionally means no edge, so without the extra one, edges between nodes without common neighbors wouldn't count as edges.
In NetworkX, any edge attribute can be used as a weight. In the following example, the weight is just called weight, and is set to the tie strength:
# Calculate weight for each edge
for v, w in G.edges:
G.edges[v, w]["weight"] = tie_strength(G, v, w)
# Store weights in a list
edge_weights = [G.edges[v, w]["weight"] for v, w in G.edges]
The edge weights can be passed to spring_layout() in order to push strongly connected nodes even closer together, shown as follows:
weighted_pos = nx.spring_layout(G, pos=karate_pos, k=0.3, weight="weight")
By specifying the pos parameter of spring_layout(), karate_pos is used as the starting point of the new layout. Putting all of this together, the following code visualizes the weighted network:
# Draw network with edge color determined by weight
nx.draw_networkx(
G, weighted_pos, width=8, node_color=node_color,
edge_color=edge_weights, edge_cmap=plt.cm.Blues,
edge_vmin=0, edge_vmax=6)
# Draw solid/dashed lines on top of internal/external edges
nx.draw_networkx_edges(
G, weighted_pos, edgelist=internal, edge_color="gray")
nx.draw_networkx_edges(
G, weighted_pos, edgelist=external, edge_color="gray", style="dashed")
To color the edges, the edge weights are passed to draw_networkx(). NetworkX then generates the colors by mapping them to colors using a color map. In this case, colors range from light blue (low weight) to dark blue (high weight). The weighted edges are drawn with a width of eight pixels to make them more visible. The edges are also drawn a second time on top of the first; this time, one pixel wide and either solid (for internal edges) or dashed (for external edges). The final visualization will resemble the following:

The preceding screenshot makes it possible to visualize the strength of friendships, which splinter club each member joined, and which friendships were divided between clubs. While simple, the previous analysis of the karate club network enables some powerful insights. The friendships that were split between the two new clubs were typically weaker than others. Mr. Hi (node 0) and John A. (node 33) can both be seen in the center of their respective club, suggesting that they played an important role in the break-up of the original club and the formation of the new ones. If this analysis had been available to the original members of Zachary's karate club, perhaps it might have helped them strengthen the necessary relationships to keep the group together. This example has only scratched the surface of the features available in NetworkX, but hopefully it has demonstrated how powerful those features can be.