Matplotlib 3D绘制数据集列sin/cos曲线报错及保存问题求助
问题解决与代码修正
错误原因分析
第一段代码报错
ax.plot3D要求输入的x、y、z参数为长度一致的一维数组(对应单条曲线的坐标)。你传入的np.cos(data[:,:100])和np.sin(data[:,:100])是二维数组(形状(999,100)),与一维的tgrid无法匹配,导致广播失败触发维度错误。
第二段代码无法保存图片
- 循环内重复创建
ax = plt.axes(projection='3d'),每次都会生成新的3D坐标轴,之前绘制的曲线被覆盖,最终仅保留最后一次创建的空图或单条曲线。 - 维度不匹配:
data_x[jj,:]是长度为100的行数据,而tgrid是长度999的数组,x、y、z长度不一致,实际运行会触发另一个维度错误。
修正后的代码
根据你的需求(绘制999条曲线),假设每条曲线对应数据集的一行(共999行,每行100个时间点),修正代码如下:
import numpy as np import matplotlib.pyplot as plt # 替换为你的实际数据集 data = np.random.rand(999, 100) plt.figure(figsize=(4.3, 4)) # 仅创建一次3D坐标轴 ax = plt.axes(projection='3d') # 时间点对应每行的100个数据,所以tgrid长度为100 tgrid = np.arange(0, 100) # 循环每一行,绘制999条曲线 for row_idx in range(data.shape[0]): y_vals = np.cos(data[row_idx, :]) z_vals = np.sin(data[row_idx, :]) ax.plot3D(tgrid, y_vals, z_vals, '-', color='black', linewidth=1.5) # 设置坐标轴标签 ax.set_xlabel(r'$t$') ax.set_ylabel(r'$\cos(\theta)$') ax.set_zlabel(r'$\sin(\theta)$') # 统一添加图例(所有曲线样式一致) ax.legend(['True'], loc='best', prop={'size': 12}) # 保存图片,需在plt.show()之前调用,避免保存空图 plt.savefig('data.pdf') plt.show()
如果你的需求是绘制每一列的曲线(共100条,每列999个时间点),只需调整循环和tgrid:
import numpy as np import matplotlib.pyplot as plt data = np.random.rand(999, 100) plt.figure(figsize=(4.3, 4)) ax = plt.axes(projection='3d') # 时间点对应每列的999个数据,tgrid长度为999 tgrid = np.arange(0, 999) # 循环每一列,绘制100条曲线 for col_idx in range(data.shape[1]): y_vals = np.cos(data[:, col_idx]) z_vals = np.sin(data[:, col_idx]) ax.plot3D(tgrid, y_vals, z_vals, '-', color='black', linewidth=1.5) ax.set_xlabel(r'$t$') ax.set_ylabel(r'$\cos(\theta)$') ax.set_zlabel(r'$\sin(\theta)$') ax.legend(['True'], loc='best', prop={'size': 12}) plt.savefig('data.pdf') plt.show()
关键注意事项
- 确保
tgrid的长度与每条曲线的y、z数据长度完全一致。 - 仅在循环外创建一次3D坐标轴,避免重复创建导致曲线被覆盖。
plt.savefig()需在plt.show()之前调用,否则会保存空白图片(因为plt.show()会清空当前绘图上下文)。
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

