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

Matplotlib 3D绘图报错:Input z must be 2D, not 1D 求助

问题

我有一个存储在DataFrame中的TF-IDF矩阵,已通过TSNE进行降维处理:

tsne_vecs_clarke2 = TSNE(n_components=3, perplexity=30.0, init='pca', learning_rate='auto').fit_transform(clarke)

clarke['component1'] = tsne_vecs_clarke2[:,0]
clarke['component2'] = tsne_vecs_clarke2[:,1]
clarke['component3'] = tsne_vecs_clarke2[:,2]

此前我用Seaborn绘制了2D散点图:

sns.scatterplot(x=clarke['component3'], y=clarke['component2'], hue=clarke['0inclusion'], data=clarke).set(title="T-SNE projection ")

现在希望通过3D绘图获取更多信息,但使用Matplotlib绘制3D图时出现TypeError:Input z must be 2D, not 1D,相关代码及报错信息如下:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

x = clarke['component1']
y = clarke['component2']
z = clarke['component3']

fig = plt.figure()
ax = plt.axes(projection='3d')
ax.contour3D(x, y, z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

报错栈:

TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_16936/3386285865.py in <module>
      1 fig = plt.figure()
      2 ax = plt.axes(projection='3d')
----> 3 ax.contour3D(x, y, z, 50, cmap='binary')
      4 ax.set_xlabel('x')
      5 ax.set_ylabel('y')

~\anaconda3\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py in contour(self, X, Y, Z, extend3d, stride, zdir, offset, *args, **kwargs)
   2173 
   2174         jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
-> 2175         cset = super().contour(jX, jY, jZ, *args, **kwargs)
   2176         self.add_contour_set(cset, extend3d, stride, zdir, offset)
   2177 

~\anaconda3\lib\site-packages\matplotlib\__init__.py in inner(ax, data, *args, **kwargs)
   1359     def inner(ax, *args, data=None, **kwargs):
   1360         if data is None:
-> 1361             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1362 
   1363         bound = new_sig.bind(ax, *args, **kwargs)

~\anaconda3\lib\site-packages\matplotlib\axes\_axes.py in contour(self, *args, **kwargs)
   6418     def contour(self, *args, **kwargs):
   6419         kwargs['filled'] = False
-> 6420         contours = mcontour.QuadContourSet(self, *args, **kwargs)
   6421         self._request_autoscale_view()
   6422         return contours

~\anaconda3\lib\site-packages\matplotlib\contour.py in __init__(self, ax, levels, filled, linewidths, linestyles, hatches, alpha, origin, extent, cmap, colors, norm, vmin, vmax, extend, antialiased, nchunk, locator, transform, *args, **kwargs)
    775         self._transform = transform
    776 
-> 777         kwargs = self._process_args(*args, **kwargs)
    778         self._process_levels()
    779 

~\anaconda3\lib\site-packages\matplotlib\contour.py in _process_args(self, corner_mask, *args, **kwargs)
   1364             self._corner_mask = corner_mask
   1365 
-> 1366             x, y, z = self._contour_args(args, kwargs)
   1367 
   1368             _mask = ma.getmask(z)

~\anaconda3\lib\site-packages\matplotlib\contour.py in _contour_args(self, args, kwargs)
   1422             args = args[1:]
   1423         elif Nargs <= 4:
-> 1424             x, y, z = self._check_xyz(args[:3], kwargs)
   1425             args = args[3:]
   1426         else:

~\anaconda3\lib\site-packages\matplotlib\contour.py in _check_xyz(self, args, kwargs)
   1450 
   1451         if z.ndim != 2:
-> 1452             raise TypeError(f"Input z must be 2D, not {z.ndim}D")
   1453         if z.shape[0] < 2 or z.shape[1] < 2:
   1454             raise TypeError(f"Input z must be at least a (2, 2) shaped array, ")

TypeError: Input z must be 2D, not 1D

解决方案

问题根源

ax.contour3D() 用于绘制3D等高线图,要求输入的z是二维数组(代表曲面高度的网格数据),但你的数据是TSNE降维后的离散散点(每个样本对应一组(x,y,z)坐标),属于一维数组,因此触发类型错误。

正确实现:3D散点图

改用ax.scatter3D()绘制3D散点图,和你之前的2D散点图逻辑一致,同时可以保留分类着色的功能:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

# 提取数据
x = clarke['component1']
y = clarke['component2']
z = clarke['component3']
category = clarke['0inclusion']

# 创建绘图对象
fig = plt.figure(figsize=(10, 8))
ax = plt.axes(projection='3d')

# 绘制3D散点,按分类着色
scatter = ax.scatter3D(x, y, z, c=category, cmap='viridis')

# 设置标签与标题
ax.set_xlabel('Component 1')
ax.set_ylabel('Component 2')
ax.set_zlabel('Component 3')
ax.set_title('3D T-SNE Projection')

# 添加颜色图例
plt.colorbar(scatter, label='0inclusion')

plt.show()

额外提示

  • 若需要交互旋转视角查看3D效果,在Jupyter环境下可将%matplotlib inline替换为%matplotlib notebook。
  • 若执意要绘制3D曲面/等高线,需先通过插值(如scipy.interpolate.griddata)将散点转换为网格数据,但这对TSNE降维结果无实际意义——TSNE是将高维数据映射为低维离散点,不存在连续曲面的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:24:56