如何将循环加载的多条轨迹绘制在同一Matplotlib 3D坐标系中?
问题根源
你遇到的问题和3D/2D绘图逻辑差异无关,纯粹是代码执行顺序的问题:
- 初始版本把
plt.figure().add_subplot(projection="3d")写在循环内部,每次迭代都会新建一个独立画布和3D坐标轴,每条轨迹自然被画在单独的新图里 - 第二次修改把绘图语句也移到了循环外,等循环全部执行完时,
x_list/y_list/z_list三个变量只保留了最后一组数据的赋值,当然只能画出最后一条轨迹
正确实现方案
核心原则:画布和3D坐标轴只需要在循环开始前创建1次,循环内部仅完成数据加载、相空间坐标转换、往已有坐标轴上追加轨迹的操作。另外可以把不需要重复计算的色图生成逻辑也移到循环外,减少冗余计算。
修正后的完整代码如下:
import matplotlib.pyplot as plt import numpy as np import pandas as pd # 循环外执行一次性初始化 fig = plt.figure() ax = fig.add_subplot(projection="3d") # 仅创建1次3D坐标轴 # 提前生成所有轨迹对应的配色,无需循环内重复计算 cmap = plt.get_cmap("tab20c_r") segment_colors = cmap(np.linspace(0, 1, len(Subjects))) # 循环内逐组处理数据、绘制轨迹 for idx, subject in enumerate(Subjects): data = np.loadtxt("path/to/files...") # 转换3D相空间坐标 x = pd.Series(data) y = x.shift(Mean_Lag) z = x.shift(Mean_Lag * 2) # 往提前创建好的3D轴上追加绘制当前轨迹 ax.plot(x, y, z, lw=0.5, c=segment_colors[idx]) plt.show()
补充说明
- 代码里用
enumerate(Subjects)直接获取每组数据的索引,比在循环内反复调用Subjects.index(subject)效率更高,也能避免列表存在重复元素时索引匹配错误的问题 - 不管是2D还是3D绘图,只要需要将多个元素绘制在同一张图中,逻辑都是一致的:提前创建1次画布和坐标轴,循环内只做追加绘图的操作。你之前绘制2D图没遇到同类问题,是因为没有在循环内写新建画布的语句,matplotlib会默认将绘图元素叠加到当前激活的坐标轴上。
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

