文章绘图第 31 章

SANKEYDIAGRAM

绘图 · 第 31 / 36 章

SANKEYDIAGRAM
Python58 行
# pip install plotly
import plotly.graph_objects as go

# 节点定义
labels = ["Source A", "Source B", "Source C",
          "Process 1", "Process 2", "Output X", "Output Y"]

# 节点颜色(按主题色循环)
node_colors = [
    "#A8552E", "#35666E", "#D0A64F",      # 源
    "#3F2E18", "#7E8F52",                 # 处理
    "#A8552E", "#35666E",                 # 输出
]

# 流:源索引 → 目标索引,流量值
source = [0, 0, 1, 1, 2, 3, 4]
target = [3, 4, 3, 4, 4, 5, 6]
value  = [30, 20, 25, 15, 18, 55, 53]

# 流的颜色(半透明,接近源节点色)
link_colors = [
    "rgba(168, 85, 46, 0.4)",
    "rgba(168, 85, 46, 0.4)",
    "rgba(53, 102, 110, 0.4)",
    "rgba(53, 102, 110, 0.4)",
    "rgba(208, 166, 79, 0.4)",
    "rgba(63, 46, 24, 0.4)",
    "rgba(126, 143, 82, 0.4)",
]

fig = go.Figure(data=[go.Sankey(
    node=dict(
        pad=20,
        thickness=20,
        line=dict(color="white", width=1.5),
        label=labels,
        color=node_colors,
        hovertemplate="%{label}<br>Total: %{value}<extra></extra>",
    ),
    link=dict(
        source=source,
        target=target,
        value=value,
        color=link_colors,
        hovertemplate="%{source.label} → %{target.label}<br>%{value}<extra></extra>",
    ),
)])

fig.update_layout(
    title="Sankey Diagram — Basic",
    font=dict(size=12, color="#3F2E18"),
    paper_bgcolor="#F7F3EC",
    plot_bgcolor="#F7F3EC",
    width=900, height=500,
)

# fig.show()
fig.write_html("sankey.html") #动态图

用户路径桑基图

用户路径桑基图
Python63 行
import plotly.graph_objects as go

# 用户路径:首页 → 分类页 → 详情页 → 下单/离开
labels = [
    "Home",                    # 0
    "Category",                # 1
    "Detail",                  # 2
    "Cart",                    # 3
    "Checkout",                # 4
    "Purchase",                # 5
    "Bounce",                  # 6
    "Exit",                    # 7
]

# 节点颜色
node_colors = [
    "#A8552E", "#35666E", "#D0A64F", "#3F2E18", "#7E8F52",
    "#A8552E", "#35666E", "#3F2E18",
]

source = [0, 0, 1, 1, 2, 2, 3, 3, 4]
target = [1, 6, 2, 7, 3, 7, 4, 7, 5]
value  = [700, 300, 500, 200, 350, 150, 250, 100, 200]

# 流颜色按源节点
link_colors = [
    "rgba(168, 85, 46, 0.35)",    # Home → Category
    "rgba(168, 85, 46, 0.35)",    # Home → Bounce
    "rgba(53, 102, 110, 0.35)",   # Category → Detail
    "rgba(53, 102, 110, 0.35)",   # Category → Exit
    "rgba(208, 166, 79, 0.35)",   # Detail → Cart
    "rgba(208, 166, 79, 0.35)",   # Detail → Exit
    "rgba(63, 46, 24, 0.35)",     # Cart → Checkout
    "rgba(63, 46, 24, 0.35)",     # Cart → Exit
    "rgba(126, 143, 82, 0.35)",   # Checkout → Purchase
]

fig = go.Figure(data=[go.Sankey(
    arrangement="snap",
    node=dict(
        pad=25,
        thickness=25,
        line=dict(color="white", width=1.5),
        label=labels,
        color=node_colors,
    ),
    link=dict(
        source=source,
        target=target,
        value=value,
        color=link_colors,
    ),
)])

fig.update_layout(
    title="User Journey Sankey",
    font=dict(size=13, color="#3F2E18"),
    paper_bgcolor="#F7F3EC",
    plot_bgcolor="#F7F3EC",
    width=1000, height=550,
)

fig.write_html("sankey2.html") #动态图

自定义样式的 Plotly 桑基图

自定义样式的 Plotly 桑基图
Python60 行
import plotly.graph_objects as go

labels = [
    "Source A", "Source B", "Source C",
    "Stage 1", "Stage 2",
    "Output X", "Output Y", "Loss",
]

node_colors = [
    "#A8552E", "#35666E", "#D0A64F",
    "#3F2E18", "#7E8F52",
    "#A8552E", "#35666E", "#3F2E18",
]

source = [0, 0, 1, 1, 2, 3, 3, 4, 4]
target = [3, 4, 3, 4, 4, 5, 7, 6, 7]
value  = [30, 20, 25, 15, 18, 40, 15, 30, 8]

# 流颜色:按目标节点
def link_color(target_idx, alpha=0.35):
    c = node_colors[target_idx].lstrip("#")
    r, g, b = int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16)
    return f"rgba({r},{g},{b},{alpha})"

link_colors = [link_color(t) for t in target]

fig = go.Figure(data=[go.Sankey(
    arrangement="snap",
    node=dict(
        pad=30,
        thickness=25,
        line=dict(color="white", width=2),
        label=labels,
        color=node_colors,
        hovertemplate="<b>%{label}</b><br>Total: %{value}<extra></extra>",
    ),
    link=dict(
        source=source,
        target=target,
        value=value,
        color=link_colors,
        hovertemplate="%{source.label} → %{target.label}<br>"
                      "Flow: %{value}<extra></extra>",
    ),
)])

fig.update_layout(
    title=dict(
        text="Sankey Diagram — Custom Style",
        font=dict(size=16, color="#3F2E18"),
        x=0.5, xanchor="center",
    ),
    font=dict(size=12, color="#3F2E18", family="Arial"),
    paper_bgcolor="#F7F3EC",
    plot_bgcolor="#F7F3EC",
    width=1000, height=600,
    margin=dict(l=30, r=30, t=80, b=30),
)

fig.write_html("sankey3.html") #动态图