Tutorials

Centrality Measures with NetworkX

Not all nodes in a network are equally important. Centrality measures assign a numerical score to each node reflecting its role: how many connections it has, how often it lies on the shortest path between others, how quickly it can reach the whole network, or how well-connected its neighbors are. Different centrality measures answer different questions — a node with high betweenness might be a critical bridge, while one with high eigenvector centrality is influential because its neighbors are also influential. NetworkX computes all of these in a single function call.

### Degree Centrality

Degree centrality is the simplest measure: it's just the fraction of other nodes that a node is directly connected to. High degree means many direct connections — these are the "hubs" of a network.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
deg = nx.degree_centrality(G)

# Top 5 nodes by degree centrality
top5 = sorted(deg, key=deg.get, reverse=True)[:5]
for n in top5:
    print(f"  Node {n:2d}: degree centrality = {deg[n]:.3f}")

pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(7, 6))
sizes = [deg[n] * 3000 for n in G.nodes()]
nx.draw(G, pos, node_size=sizes, node_color=list(deg.values()),
        cmap="YlOrRd", with_labels=True, font_size=7, edge_color="gray", width=0.5)
plt.title("Degree Centrality (node size ∝ degree)")
plt.tight_layout()
plt.show()
  Node 33: degree centrality = 0.515
  Node  0: degree centrality = 0.485
  Node 32: degree centrality = 0.364
  Node  2: degree centrality = 0.303
  Node  1: degree centrality = 0.273
/var/folders/8l/xyy39wqj1c71tdcxq7vndwvr0000gn/T/ipykernel_68545/2047753355.py:18: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  plt.tight_layout()
- `nx.degree_centrality(G)` returns a dictionary mapping each node to its normalized degree (connections / (n−1)).
- Scaling node size by `deg[n] * 3000` makes hubs visually prominent — larger nodes have more connections.
- `cmap="YlOrRd"` maps centrality values to colors from yellow (low) to red (high), reinforcing the visual encoding.

### Betweenness Centrality

Betweenness centrality counts how often a node appears on the shortest path between every pair of other nodes. High betweenness nodes are brokers or bridges — removing them would disconnect large parts of the network.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
bet = nx.betweenness_centrality(G, normalized=True)

top5 = sorted(bet, key=bet.get, reverse=True)[:5]
for n in top5:
    print(f"  Node {n:2d}: betweenness = {bet[n]:.4f}")

pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(7, 6))
sizes = [bet[n] * 8000 + 100 for n in G.nodes()]
nx.draw(G, pos, node_size=sizes, node_color=list(bet.values()),
        cmap="YlOrRd", with_labels=True, font_size=7, edge_color="gray", width=0.5)
plt.title("Betweenness Centrality (node size ∝ betweenness)")
plt.tight_layout()
plt.show()
  Node  0: betweenness = 0.4376
  Node 33: betweenness = 0.3041
  Node 32: betweenness = 0.1452
  Node  2: betweenness = 0.1437
  Node 31: betweenness = 0.1383
/var/folders/8l/xyy39wqj1c71tdcxq7vndwvr0000gn/T/ipykernel_68545/1786152941.py:17: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  plt.tight_layout()
- `normalized=True` scales scores to [0, 1] so they're comparable across graphs of different sizes.
- Nodes 0 and 33 (the two club leaders in the karate club graph) consistently have the highest betweenness — they control information flow between the two sides of the eventual split.
- The `+ 100` in the size formula ensures even low-betweenness nodes are still visible.

### Closeness Centrality

Closeness centrality measures how quickly a node can reach all others — it's the inverse of the average shortest-path distance to every other node. High closeness means you're centrally located, not necessarily well-connected.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
clo = nx.closeness_centrality(G)

top5 = sorted(clo, key=clo.get, reverse=True)[:5]
for n in top5:
    print(f"  Node {n:2d}: closeness = {clo[n]:.4f}")

pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(7, 6))
sizes = [clo[n] * 2000 for n in G.nodes()]
nx.draw(G, pos, node_size=sizes, node_color=list(clo.values()),
        cmap="YlOrRd", with_labels=True, font_size=7, edge_color="gray", width=0.5)
plt.title("Closeness Centrality (node size ∝ closeness)")
plt.tight_layout()
plt.show()
  Node  0: closeness = 0.5690
  Node  2: closeness = 0.5593
  Node 33: closeness = 0.5500
  Node 31: closeness = 0.5410
  Node  8: closeness = 0.5156
/var/folders/8l/xyy39wqj1c71tdcxq7vndwvr0000gn/T/ipykernel_68545/2541685066.py:17: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  plt.tight_layout()
- Closeness centrality values cluster more tightly than betweenness — most nodes in a well-connected graph are roughly equally central by this measure.
- For disconnected graphs, `nx.closeness_centrality` uses a variant that accounts for only the reachable portion of the graph.
- A node with high closeness but low betweenness is well-positioned but doesn't bridge otherwise-disconnected groups.

### Comparing All Centrality Measures

Plotting all four centrality measures side by side on the same graph layout reveals which nodes are important under each definition — and how often they agree.

import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
measures = {
    "Degree":      nx.degree_centrality(G),
    "Betweenness": nx.betweenness_centrality(G),
    "Closeness":   nx.closeness_centrality(G),
    "Eigenvector": nx.eigenvector_centrality(G, max_iter=1000),
}

pos = nx.spring_layout(G, seed=42)
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
for ax, (name, scores) in zip(axes.ravel(), measures.items()):
    sizes = [scores[n] * 3000 + 50 for n in G.nodes()]
    nx.draw(G, pos, ax=ax, node_size=sizes,
            node_color=list(scores.values()), cmap="YlOrRd",
            with_labels=True, font_size=6, edge_color="gray", width=0.4)
    ax.set_title(name)
plt.suptitle("Four Centrality Measures on the Karate Club Graph", y=1.01)
plt.tight_layout()
plt.show()
- `nx.eigenvector_centrality` scores a node by the sum of its neighbors' scores — influential nodes are those connected to other influential nodes. `max_iter=1000` prevents convergence failures on some graphs.
- Comparing layouts: degree and eigenvector centrality often agree (hubs are connected to other hubs); betweenness highlights bridges; closeness highlights geographically central nodes.
- All four use the same `pos` layout so the visual positions are identical — only the node sizes and colors change, isolating the effect of each measure.

Centrality measures are one of the most actionable outputs of network analysis. To explore how information spreads through a network via random walks, see [PageRank with NetworkX](/tutorials/pagerank-with-networkx).