目录4

文章绘图第 32 章

NETWORK

绘图 · 第 32 / 36 章

基础网络图

chart_118

基础网络图
Python39 行
import matplotlib.pyplot as plt
import networkx as nx

COLORS = ["#A8552E", "#35666E", "#D0A64F", "#3F2E18", "#7E8F52"]
BG = "#F7F3EC"

# 构造图
G = nx.karate_club_graph()   # 经典空手道俱乐部数据集

fig, ax = plt.subplots(figsize=(10, 9))

# 布局
pos = nx.spring_layout(G, seed=42, k=0.8)

# 画边
nx.draw_networkx_edges(G, pos, ax=ax,
                       edge_color="#3F2E18",
                       width=0.8, alpha=0.4)

# 画节点
nx.draw_networkx_nodes(G, pos, ax=ax,
                       node_color=COLORS[0],
                       node_size=280,
                       edgecolors="white",
                       linewidths=1.5,
                       alpha=0.9)

# 画标签
nx.draw_networkx_labels(G, pos, ax=ax,
                        font_size=8,
                        font_color="white",
                        font_weight="bold")

ax.set_title("Network Graph — Basic",
             fontsize=15, color=COLORS[3], pad=12)
ax.axis("off")

plt.tight_layout()
plt.show()

有向图 + 权重边

chart_119

有向图 + 权重边
Python65 行
import matplotlib.pyplot as plt
import networkx as nx

COLORS = ["#A8552E", "#35666E", "#D0A64F", "#3F2E18", "#7E8F52"]
BG = "#F7F3EC"

# 有向图
G = nx.DiGraph()
edges = [
    ("A", "B", 5), ("A", "C", 3),
    ("B", "D", 4), ("C", "D", 2),
    ("C", "E", 6), ("D", "F", 3),
    ("E", "F", 4), ("B", "E", 2),
]
G.add_weighted_edges_from(edges)

fig, ax = plt.subplots(figsize=(10, 7))

pos = nx.spring_layout(G, seed=42, k=1.2)

# 边的宽度按权重
weights = [G[u][v]["weight"] for u, v in G.edges()]
widths = [w * 0.6 for w in weights]

nx.draw_networkx_edges(
    G, pos, ax=ax,
    edge_color=COLORS[1],
    width=widths,
    alpha=0.5,
    arrows=True,
    arrowsize=18,
    arrowstyle="-|>",
    connectionstyle="arc3,rad=0.1",
)

# 节点
node_sizes = [400 + G.degree(n) * 100 for n in G.nodes()]
nx.draw_networkx_nodes(G, pos, ax=ax,
                       node_color=COLORS[0],
                       node_size=node_sizes,
                       edgecolors="white",
                       linewidths=2.0,
                       alpha=0.9)

# 标签
nx.draw_networkx_labels(G, pos, ax=ax,
                        font_size=11,
                        font_color="white",
                        font_weight="bold")

# 边权标签
edge_labels = nx.get_edge_attributes(G, "weight")
nx.draw_networkx_edge_labels(
    G, pos, edge_labels=edge_labels, ax=ax,
    font_size=9, font_color=COLORS[3],
    bbox=dict(boxstyle="round,pad=0.2",
              facecolor=BG, edgecolor="none", alpha=0.8),
)

ax.set_title("Directed Weighted Network",
             fontsize=15, color=COLORS[3], pad=12)
ax.axis("off")

plt.tight_layout()
plt.show()

按度数渐变着色

chart_120

按度数渐变着色
Python49 行
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.colors import LinearSegmentedColormap

BG = "#F7F3EC"
CMAP = LinearSegmentedColormap.from_list(
    "theme", ["#D0A64F", "#A8552E", "#3F2E18"], N=256
)

G = nx.karate_club_graph()
degrees = dict(G.degree())
node_colors = [degrees[n] for n in G.nodes()]
node_sizes = [300 + degrees[n] * 80 for n in G.nodes()]

fig, ax = plt.subplots(figsize=(10, 9))

pos = nx.spring_layout(G, seed=42, k=0.8)

nx.draw_networkx_edges(G, pos, ax=ax,
                       edge_color="#3F2E18",
                       width=0.8, alpha=0.3)

nodes = nx.draw_networkx_nodes(
    G, pos, ax=ax,
    node_color=node_colors,
    node_size=node_sizes,
    cmap=CMAP,
    edgecolors="white",
    linewidths=1.8,
    alpha=0.95,
)

nx.draw_networkx_labels(G, pos, ax=ax,
                        font_size=8,
                        font_color="white",
                        font_weight="bold")

# 色条
cbar = fig.colorbar(nodes, ax=ax, shrink=0.7, pad=0.02)
cbar.set_label("Degree", fontsize=11, color="#3F2E18")
cbar.ax.tick_params(colors="#3F2E18")
cbar.outline.set_edgecolor("#3F2E18")

ax.set_title("Network — Degree Centrality",
             fontsize=15, color="#3F2E18", pad=12)
ax.axis("off")

plt.tight_layout()
plt.show()

带边捆绑的分层网络

chart_121

带边捆绑的分层网络
Python61 行
import matplotlib.pyplot as plt
import networkx as nx

COLORS = ["#A8552E", "#35666E", "#D0A64F", "#3F2E18", "#7E8F52"]
BG = "#F7F3EC"

# 分层图:3 层
G = nx.DiGraph()
G.add_nodes_from([
    ("A1", {"layer": 0}), ("A2", {"layer": 0}),
    ("B1", {"layer": 1}), ("B2", {"layer": 1}), ("B3", {"layer": 1}),
    ("C1", {"layer": 2}), ("C2", {"layer": 2}),
])
G.add_edges_from([
    ("A1", "B1"), ("A1", "B2"),
    ("A2", "B2"), ("A2", "B3"),
    ("B1", "C1"), ("B2", "C1"), ("B2", "C2"),
    ("B3", "C2"),
])

# 按层分组
layers = [[n for n, d in G.nodes(data=True) if d["layer"] == i]
          for i in range(3)]

fig, ax = plt.subplots(figsize=(10, 7))

pos = nx.multipartite_layout(G, subset_key="layer")

# 边的颜色按源层
edge_colors = []
for u, v in G.edges():
    layer = G.nodes[u]["layer"]
    edge_colors.append(COLORS[layer])

nx.draw_networkx_edges(
    G, pos, ax=ax,
    edge_color=edge_colors,
    width=1.8, alpha=0.5,
    arrows=True, arrowsize=16,
)

# 按层给节点着色
node_colors = [COLORS[G.nodes[n]["layer"]] for n in G.nodes()]
nx.draw_networkx_nodes(G, pos, ax=ax,
                       node_color=node_colors,
                       node_size=700,
                       edgecolors="white",
                       linewidths=2.0,
                       alpha=0.9)

nx.draw_networkx_labels(G, pos, ax=ax,
                        font_size=11,
                        font_color="white",
                        font_weight="bold")

ax.set_title("Layered Network (Multipartite)",
             fontsize=15, color=COLORS[3], pad=12)
ax.axis("off")

plt.tight_layout()
plt.show()