pythonmatplotlibdimension

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


I have a tf-idf matrix in a dataframe. I ran it through 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]

When I plotted clarke['component2'] against clarke['component2'] with the following code, I get this plot:

sns.scatterplot(x=clarke['component3'], y=clarke['component2'], hue=clarke['0inclusion'],

data=clarke).set(title="T-SNE projection ")

tsne projection

I would like to look at it in 3D to get more insights. I tried to plot it in 3D matplotlib but I ran into a TypeError stating that 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

I am not sure how to fix this issue. Any help will be much appreciated.


Solution

  • If you're doing PCA you probably want a scatterplot, which you can make with ax.scatter3D(x, y, z).

    If you do want this as a contour, see this answer for how to structure your data: Why does pyplot.contour() require Z to be a 2D array?