Python matplotlib 3D绘图报广播错误及Line3D无_verts3d属性问题
问题根因
两个报错本质是同一个问题导致的:matplotlib的Axes3D.plot()方法要求传入的x、y、z三组坐标值必须是长度完全相等的一维数组,不支持形状为(n,1)的二维列向量作为输入。
- 当你把
targets调整为形状(1000,)的一维数组时,xs、zs仍然是(1000,1)的二维数组,matplotlib内部做数组运算时无法完成形状广播,触发第一个ValueError。 - 当你把
targets也保持为(1000,1)的二维形状时,三个输入全是二维列向量,Line3D对象无法正确解析三维顶点数据,初始化失败,就会触发'Line3D' object has no attribute '_verts3d'的AttributeError。 - 原代码注释里“绘图需要单独调整targets形状、绘图后还要还原形状”的逻辑是错误的,问题从来不是targets的形状单独有问题,而是三个输入数组的维度没有统一成一维。
修复方案
核心操作是保证传入ax.plot()的三个数组全部为形状一致的一维数组,不需要反复对targets做reshape操作,两种实现都可以:
- 方案1:如果后续代码不需要保留数组原有的
(n,1)二维结构,直接在绘图前把三个数组全部展平为一维即可
# 展平所有坐标数组为一维 xs = xs.reshape(-1) zs = zs.reshape(-1) targets = targets.reshape(-1) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot(xs, zs, targets) ax.set_xlabel('xs') ax.set_ylabel('zs') ax.set_zlabel('Targets') ax.view_init(azim=100) plt.show()
- 方案2:如果后续计算还要用到数组原来的二维形状,绘图时临时展平参数即可,不需要修改原数组
fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 传入参数时临时展平,不改动原数组形状 ax.plot(xs.flatten(), zs.flatten(), targets.flatten()) ax.set_xlabel('xs') ax.set_ylabel('zs') ax.set_zlabel('Targets') ax.view_init(azim=100) plt.show()
避坑提示:不要只调整targets的形状,必须保证三个输入参数的维度统一,才能同时解决两个报错。原代码里绘图后再把targets reshape回(observations,1)的操作完全是多余的,可以删掉。
内容的提问来源于stack exchange,提问作者Shaaran S.R.
相关产品推荐
相关产品推荐

