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

Matplotlib嵌套for循环绘制时间序列(轨迹)子图问题咨询

问题根因与解决方案

1. 嵌套循环正确绘制全部5组时间序列的方法

根因

你当前代码的逻辑是:每遍历一组时间序列,就重复创建一次所有位置的子图,新创建的子图会直接覆盖同位置已有的旧子图,所以最后只会保留最后一组(第5组)的绘制结果。如果把plt.show()放在第二层循环外侧,会在第一组序列绘制完成后直接渲染弹窗,阻塞后续代码执行,所以只能看到第一组结果。

修正逻辑

  • 提前计算所有状态对应的子图行列数,一次性创建全部子图,避免重复创建覆盖
  • 第一层循环仅遍历5组序列数据,第二层循环直接在已创建好的对应子图上叠加绘制曲线

2. 同一y变量设置统一坐标轴范围的方法

有两种常用实现方案:

  • 自动共享:创建子图时指定sharey='row'或sharey='col',相同行/列的子图会自动同步y轴取值范围,适合同类状态排列在同一行/列的场景
  • 手动统一:提前遍历所有序列的所有状态值,计算每类状态(关节角度/速度/肌肉激活度)的全局最大、最小值,绘制完成后统一给同类子图设置ylim,适配自定义范围需求

修正后可运行代码

import numpy as np
import matplotlib.pyplot as plt

# ---------------------- 提前准备参数,一次性创建子图 ----------------------
# 假设所有轨迹的状态定义一致,取第一个轨迹的状态计算子图行列
stateNames = list(Traj_List[0].getStateNames())
numStates = len(stateNames)
dim = np.sqrt(numStates)
if dim == np.ceil(dim):
    numRows = int(dim)
    numCols = int(dim)
else:
    numCols = int(np.min([numStates, 4]))
    numRows = int(np.floor(numStates / 4))
    if not numStates % 4 == 0:
        numRows += 1

# 一次性创建所有子图,sharey='row'表示同行子图共享y轴,可按需调整为col或关闭
fig, axs = plt.subplots(numRows, numCols, figsize=(38, 55), sharey='row')
axs = axs.flatten() # 把子图数组转为一维,方便按索引遍历

color = ['r', 'b', 'g', 'y', 'm']
lines = ["-", "--", "-.", ":", "-."]
linewidth = [3, 2.5, 3.5, 2, 3]

# ---------------------- 嵌套循环叠加绘制所有序列 ----------------------
for i in range(len(Traj_List)):
    for j in np.arange(numStates):
        # 直接在已创建的子图上绘制,不再重复创建
        ax = axs[j]
        ax.plot(Traj_List[i].getTimeMat(),
                Traj_List[i].getStateMat(stateNames[j]), 
                linestyle=lines[i], color=color[i],
                linewidth=linewidth[i], label=Label_List[i])

# ---------------------- 统一设置子图标签、范围 ----------------------
for j in np.arange(numStates):
    ax = axs[j]
    stateName = stateNames[j]
    ax.set_title(stateName)
    ax.set_xlabel('time (s)')
    ax.legend(loc='best')
    if 'value' in stateName:
        ax.set_ylabel('position (rad)')
        # 如需手动设置统一范围,可提前计算所有位置类数据的max/min,替换下面的数值
        # ax.set_ylim(min_pos, max_pos)
    elif 'speed' in stateName:
        ax.set_ylabel('speed (rad/s)')
        # ax.set_ylim(min_speed, max_speed)
    elif 'activation' in stateName:
        ax.set_ylabel('activation (-)')
        ax.set_ylim(0, 1)

fig.tight_layout()
plt.show()
plt.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:24:05