You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly子图实现按Dip编号分色的速度、温度垂直剖面并排绘制

问题根因

你之前用make_subplots搭配go.Scatter无法实现自动分色,核心是**color="Dip No."是plotly.express的高层封装能力,不是原生go.Scatter的内置参数**。px在后台会自动按指定分组字段拆分数据集,为每个独立分组生成单独绘图trace,并调用内置离散色板为每个trace分配差异化颜色。而原生go.Scatter不会自动做分组拆分,直接传入整份DataFrame时,所有数据会被合并为一个trace,自然只能显示统一颜色。

最省心的实现方案:复用px已生成的trace迁移到子图布局

这个方案完全不需要手动写分组循环、手动匹配颜色,100%复刻你之前独立绘图的分色、样式逻辑,改造成本最低:

  • 先按照你之前的逻辑,用px分别生成深度-速度、深度-温度两个独立的临时绘图对象,保留原有的Depth取反、深色主题配置
  • 构建1行2列的子图画布
  • 把两个临时绘图对象里的所有trace,逐个挂载到子图的对应位置
  • 统一调整坐标轴标签、图例显示逻辑,避免冗余

可直接运行的参考代码:

import plotly.express as px
from plotly.subplots import make_subplots

# 完全复用你原有的px绘图逻辑
# 深度-速度独立图
fig_vel = px.line(
    df,
    x="Velocity",
    y=-df["Depth"],  # 保留原有的深度取反适配逻辑
    color="Dip No.",  # 自动按观测批次分色的逻辑完全保留
    template="plotly_dark"
)
# 深度-温度独立图
fig_temp = px.line(
    df,
    x="Temperature",
    y=-df["Depth"],
    color="Dip No.",
    template="plotly_dark"
)

# 构建1行2列的子图画布
fig = make_subplots(rows=1, cols=2, subplot_titles=("深度-速度剖面", "深度-温度剖面"))

# 将两个px图的trace迁移到对应子图位置
for trace in fig_vel.data:
    fig.add_trace(trace, row=1, col=1)
for trace in fig_temp.data:
    fig.add_trace(trace, row=1, col=2)

# 统一调整布局样式
fig.update_xaxes(title_text="Velocity", row=1, col=1)
fig.update_xaxes(title_text="Temperature", row=1, col=2)
fig.update_yaxes(title_text="Depth", row=1, col=1)
fig.update_yaxes(title_text="", row=1, col=2)  # 取消第二幅图的重复Y轴标签
fig.update_layout(template="plotly_dark", showlegend=True)
fig.show()

原生go.Scatter实现路径:手动复刻px的分色逻辑

如果你希望完全基于go接口构建子图,不需要生成临时px对象,可以手动复现px的自动分组分色逻辑:

  • 先提取Dip No.字段的所有唯一观测批次
  • 调用plotly内置离散色板为每个批次预分配差异化颜色
  • 遍历每个批次筛选对应数据子集,单独添加到两个子图的对应位置,保证同一批次在两个子图上的颜色完全一致

参考代码片段:

import plotly.graph_objects as go
# 提取所有观测批次
dip_groups = df["Dip No."].unique()
# 调用plotly默认离散色板,自动保证颜色差异,无需手动指定
color_palette = px.colors.qualitative.Plotly

for idx, dip_name in enumerate(dip_groups):
    subset = df[df["Dip No."] == dip_name]
    current_color = color_palette[idx % len(color_palette)]
    
    # 添加速度剖面trace
    fig.add_trace(
        go.Scatter(
            x=subset["Velocity"],
            y=-subset["Depth"],
            mode="lines",
            name=dip_name,
            line=dict(color=current_color),
            showlegend=(idx == 0)  # 仅在第一个trace显示图例,避免重复
        ),
        row=1, col=1
    )
    # 添加温度剖面trace
    fig.add_trace(
        go.Scatter(
            x=subset["Temperature"],
            y=-subset["Depth"],
            mode="lines",
            name=dip_name,
            line=dict(color=current_color),
            showlegend=False
        ),
        row=1, col=2
    )

实现注意事项

  • 两种方案都不需要手动为Dip1、Dip2指定固定配色,颜色差异化由内置色板自动保证
  • 两个子图展示的是同一批观测的两类剖面,需要保证同一Dip批次的线条在两个子图上颜色完全一致,不能出现分色错位
  • 深色主题的配置可以直接全局统一设置,不需要在每个trace上单独配置

内容的提问来源于stack exchange,提问作者WillH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 00:15:07