如何在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
相关产品推荐
相关产品推荐

