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

如何在Plotly子图中实现多轨迹曲线展示?

修正Plotly go.Scatter多轨迹子图问题

我正在制作嵌入HTML文件用于网页展示的Plotly子图,需求是每个子图包含多条轨迹。原本使用px.line能实现多轨迹,但改用go.Scatter后生成的图表不符合预期。

当前代码

import pandas as pd 
import plotly.express as px 
import plotly.graph_objects as go
import plotly
from itertools import cycle
from plotly.subplots import make_subplots 


# 导入所需文件
F62Ext1 = pd.read_csv("F6-2_Ext1.csv")
F62Ext2 = pd.read_csv("F6-2_Ext2.csv")


# 使用savgol滤波平滑数据
from scipy.signal import savgol_filter
def savgol(x):
    return savgol_filter(x,101,6)
F62Ext1_smoothed = F62Ext1.apply(savgol)
F62Ext2_smoothed = F62Ext2.apply(savgol)

F62E1_CH1 = go.Scatter(x = F62Ext1_smoothed['Time'], y = [F62Ext1_smoothed['CH1'],F62Ext1['ActivePoke'], F62Ext1['CueLight']], name = "F62Ext1, Channel 1")
F62E2_CH1 = go.Scatter(x = F62Ext2_smoothed['Time'], y = [F62Ext2_smoothed['CH1'],F62Ext2['ActivePoke'], F62Ext2['CueLight']], name = "F62Ext2, Channel 1")

fig = make_subplots(rows = 1, cols = 2, shared_yaxes = True)
fig.add_trace(F62E1_CH1, row = 1, col = 1)
fig.add_trace(F62E2_CH1, row = 1, col = 2)

问题现状

当前代码生成的图表将多个y序列混为一团,无法区分单独的轨迹;而我期望每个子图中包含独立的多条轨迹(如平滑后的CH1、ActivePoke、CueLight各为一条清晰的线)。

附F62E1的数据字典:

{'Time': {0: 0.0, 1: 0.1, 2: 0.2, 3: 0.3, 4: 0.4},
 'CH1': {0: -0.169504148,
  1: -0.372732867,
  2: -0.323666804,
  3: -0.352484157,
  4: -0.327975913},
 'CH2': {0: -0.188884746,
  1: -0.301823346,
  2: -0.13172756,
  3: -0.456077945,
  4: -0.543653381},
 'CH3': {0: 0.03599356,
  1: -0.029965731,
  2: 0.014807156,
  3: -0.06392204,
  4: -0.041387216},
 'CH4': {0: -0.082626583,
  1: -0.071240774,
  2: -0.055854863,
  3: -0.137854075,
  4: -0.134953954},
 'CH5': {0: -0.104248439,
  1: -0.241010992,
  2: -0.249843885,
  3: -0.306350559,
  4: -0.223923059},
 'CH6': {0: -0.020229121,
  1: -0.359940514,
  2: -0.229173544,
  3: -0.266795437,
  4: -0.278069671},
 'CH7': {0: -0.209219168,
  1: -0.255944829,
  2: -0.215244963,
  3: -0.290505347,
  4: -0.28456927},
 'CH8': {0: 0.093962928,
  1: 1.2574526,
  2: 1.75068895,
  3: 1.356159013,
  4: 0.676462295},
 'CH9': {0: -0.150238434,
  1: -0.167165814,
  2: -0.057212299,
  3: -0.20998062,
  4: -0.351662263},
 'CH10': {0: -0.306078824,
  1: -0.399363635,
  2: -0.281349569,
  3: -0.53463429,
  4: -0.383537615},
 'CH11': {0: -0.189443456,
  1: -0.161361134,
  2: -0.223323043,
  3: -0.338406151,
  4: -0.339504188},
 'CH12': {0: -0.174074045,
  1: -0.230008948,
  2: -0.255067313,
  3: -0.380150306,
  4: -0.393756259},
 'CH13': {0: -0.123562058,
  1: -0.271150428,
  2: -0.251144972,
  3: -0.379664224,
  4: -0.393714865},
 'CH14': {0: -0.233391565,
  1: -0.276967731,
  2: -0.236738984,
  3: -0.44725073,
  4: -0.455074619},
 'CH15': {0: -0.234460706,
  1: -0.368129274,
  2: -0.264646375,
  3: -0.438000119,
  4: -0.40056134},
 'CH16': {0: -0.267852578,
  1: -0.224666613,
  2: -0.189448701,
  3: -0.291014541,
  4: -0.387302535},
 'ActivePoke': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0},
 'CueLight': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0},
 'Pump': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0},
 'InactivePoke': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}}

解决方案

问题根源是单个go.Scatter实例只能对应一条轨迹,你传入了多个y序列的列表,导致数据混乱。需要为每个y序列单独创建go.Scatter对象,再逐个添加到子图中。

修正后的完整代码

import pandas as pd 
import plotly.graph_objects as go
from plotly.subplots import make_subplots 
from scipy.signal import savgol_filter

# 导入数据
F62Ext1 = pd.read_csv("F6-2_Ext1.csv")
F62Ext2 = pd.read_csv("F6-2_Ext2.csv")

# 定义平滑函数
def savgol(x):
    return savgol_filter(x,101,6)
F62Ext1_smoothed = F62Ext1.apply(savgol)
F62Ext2_smoothed = F62Ext2.apply(savgol)

# 创建子图
fig = make_subplots(rows = 1, cols = 2, shared_yaxes = True)

# 第一个子图添加三条独立轨迹
fig.add_trace(go.Scatter(x=F62Ext1_smoothed['Time'], y=F62Ext1_smoothed['CH1'], name="F62Ext1 CH1(平滑)"), row=1, col=1)
fig.add_trace(go.Scatter(x=F62Ext1_smoothed['Time'], y=F62Ext1['ActivePoke'], name="F62Ext1 ActivePoke"), row=1, col=1)
fig.add_trace(go.Scatter(x=F62Ext1_smoothed['Time'], y=F62Ext1['CueLight'], name="F62Ext1 CueLight"), row=1, col=1)

# 第二个子图添加三条独立轨迹
fig.add_trace(go.Scatter(x=F62Ext2_smoothed['Time'], y=F62Ext2_smoothed['CH1'], name="F62Ext2 CH1(平滑)"), row=1, col=2)
fig.add_trace(go.Scatter(x=F62Ext2_smoothed['Time'], y=F62Ext2['ActivePoke'], name="F62Ext2 ActivePoke"), row=1, col=2)
fig.add_trace(go.Scatter(x=F62Ext2_smoothed['Time'], y=F62Ext2['CueLight'], name="F62Ext2 CueLight"), row=1, col=2)

# 调整布局(可选)
fig.update_layout(height=600, width=1200, title_text="双列多轨迹子图")
fig.show()

批量处理优化(可选)

如果需要添加更多轨迹,可用循环简化代码:

# 批量添加第一个子图的轨迹
traces_1 = [
    (F62Ext1_smoothed['CH1'], "F62Ext1 CH1(平滑)"),
    (F62Ext1['ActivePoke'], "F62Ext1 ActivePoke"),
    (F62Ext1['CueLight'], "F62Ext1 CueLight")
]
for y_data, trace_name in traces_1:
    fig.add_trace(go.Scatter(x=F62Ext1_smoothed['Time'], y=y_data, name=trace_name), row=1, col=1)

# 批量添加第二个子图的轨迹
traces_2 = [
    (F62Ext2_smoothed['CH1'], "F62Ext2 CH1(平滑)"),
    (F62Ext2['ActivePoke'], "F62Ext2 ActivePoke"),
    (F62Ext2['CueLight'], "F62Ext2 CueLight")
]
for y_data, trace_name in traces_2:
    fig.add_trace(go.Scatter(x=F62Ext2_smoothed['Time'], y=y_data, name=trace_name), row=1, col=2)

内容的提问来源于stack exchange,提问作者Hibah Mirza Chughtai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:50:34