绘制某些尺寸的PCA时会出现3D图和图例

我要通过PCA转换以下数据和标签。 标签只有0或1。

from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
import seaborn as sns
import numpy as np

fields = ["Occupancy","Temperature","Humidity","Light","CO2","HumidityRatio","NSM","WeekStatus"]
df = pd.read_csv('datatraining-updated.csv',skipinitialspace=True,usecols=fields,sep=',') 
#Get the output from pandas as a numpy matrix
final_data=df.values
#Data
X = final_data[:,1:8]  
#Labels
y = final_data[:,0]
#Normalize features
X_scaled = StandardScaler().fit_transform(X)
#Apply PCA on them
pca = PCA(n_components=7).fit(X_scaled)
#Transform them with PCA
X_reduced = pca.transform(X_scaled)

然后,我只想在3D图形中显示方差最大的3个PCA特征,如下所示

#Show variable importance
importance = pca.explained_variance_ratio_
print('Explained variation per principal component: 
{}'.format(importance))

在那之后,我只想绘制前3个最大方差特征。因此,我之前在下面的代码中选择了它们

X_reduced=X_reduced[:,[0,4,5]]

好的,这是我的问题:我可以在没有图例的情况下绘制它们。当我尝试使用以下代码绘制它们

# Create plot
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax = fig.gca(projection='3d')
colors = ("red","gray")

for data,color,group in zip(X_reduced,colors,y):
    dim1,dim2,dim3=data
    ax.scatter(dim1,dim3,c=color,edgecolors='none',label=group)

plt.title('Matplot 3d scatter plot')
plt.legend(y)
plt.show()

我收到以下错误:

plot_data-3d-pca.py:56: UserWarning: Requested projection is different from current axis projection,creating new axis with requested projection.
  ax = fig.gca(projection='3d')
plot_data-3d-pca.py:56: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance.  In a future version,a new instance will always be created and returned.  Meanwhile,this warning can be suppressed,and the future behavior ensured,by passing a unique label to each axes instance.
  ax = fig.gca(projection='3d')
Traceback (most recent call last):
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/backends/backend_gtk3.py",line 307,in idle_draw
    self.draw()
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/backends/backend_gtk3agg.py",line 76,in draw
    self._render_figure(allocation.width,allocation.height)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/backends/backend_gtk3agg.py",line 20,in _render_figure
    backend_agg.FigureCanvasAgg.draw(self)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py",line 388,in draw
    self.figure.draw(self.renderer)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/artist.py",line 38,in draw_wrapper
    return draw(artist,renderer,*args,**kwargs)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/figure.py",line 1709,in draw
    renderer,self,artists,self.suppressComposite)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/image.py",line 135,in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/unica-server/.local/lib/python3.6/site-packages/matplotlib/artist.py",**kwargs)
  File "/home/unica-server/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py",line 292,in draw
    reverse=True)):
  File "/home/unica-server/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py",line 291,in <lambda>
    key=lambda col: col.do_3d_projection(renderer),File "/home/unica-server/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py",line 545,in do_3d_projection
    ecs = (_zalpha(self._edgecolor3d,vzs) if self._depthshade else
  File "/home/unica-server/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py",line 847,in _zalpha
    rgba = np.broadcast_to(mcolors.to_rgba_array(colors),(len(zs),4))
  File "<__array_function__ internals>",line 6,in broadcast_to
  File "/home/unica-server/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py",line 182,in broadcast_to
    return _broadcast_to(array,shape,subok=subok,readonly=True)
  File "/home/unica-server/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py",line 127,in _broadcast_to
    op_flags=['readonly'],itershape=shape,order='C')
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (0,4) and requested shape (1,4)

我的y的形状为(8143,),而我的X_reduced的形状为(8143,3)

我怎么了?

编辑:我正在使用的数据可以找到here

xuanyuanwsx 回答:绘制某些尺寸的PCA时会出现3D图和图例

第一个警告Requested projection is different from current axis projection 这是因为您尝试在使用ax = fig.gca(projection='3d')创建轴后更改其投影,但是不能。而是在创建时设置投影。

要解决第二个错误,请将edgecolors='none'替换为edgecolors=None

以下更正的代码对我有用。

# Create plot
fig = plt.figure()
ax = fig.add_subplot(1,1,projection='3d') # set projection at creation of axis
# ax = fig.gca(projection='3d') # you cannot change the projection after creation
colors = ("red","gray")

for data,color,group in zip(X_reduced,colors,y):
    dim1,dim2,dim3=data
    # replace 'none' by None
    ax.scatter(dim1,dim3,c=color,edgecolors=None,label=group) 

plt.title('Matplot 3d scatter plot')
plt.legend(y)
plt.show()

编辑:以上是我对原始问题的理解。下面是mad自己回答的循环版本。

class_values = [0,1]
labels = ['Empty','Full']

n_class = len(class_values)
# allocate lists
index_class = [None] * n_class
X_reduced_class = [None] * n_class

for i,class_i in enumerate(class_values) :

    # get where are the 0s and 1s labels
    index_class[i] = np.where(np.isin(y,class_i))
    # get reduced PCA for each label
    X_reduced_class[i] = X_reduced[index_class[i]]

colors = ['blue','red']

# To getter a better understanding of interaction of the dimensions
# plot the first three PCA dimensions
fig = plt.figure(1,figsize=(8,6))
ax = Axes3D(fig,elev=-150,azim=110)

ids_plot = [0,4,5]

for i in range(n_class) : 

    # get the three interesting columns
    data  = X_reduced_class[i][:,ids_plot]

    ax.scatter(data[:,0],data[:,1],2],c=colors[i],edgecolor='k',s=40,label=labels[i])

ax.set_title("Data Visualization with 3 highest variance dimensions with PCA")
ax.set_xlabel("1st eigenvector")
ax.w_xaxis.set_ticklabels([])
ax.set_ylabel("2nd eigenvector")
ax.w_yaxis.set_ticklabels([])
ax.set_zlabel("3rd eigenvector")
ax.w_zaxis.set_ticklabels([])

ax.legend()

plt.show()
,

我以不同的方式解决了这个错误。

我不知道对于每个标签,我都必须执行不同的散点图。感谢this post,我找到了答案。

我的解决方案是首先将标签和数据从一个类中分离出来,然后对另一类进行相同的处理。最后,我用不同的散点图分别绘制它们。因此,首先,我确定不同的标签(我只有两个标签,0或1)及其数据(它们对应的Xs)。

#Get where are the 0s and 1s labels
index_class1 = np.where(np.isin(y,0))
index_class2 = np.where(np.isin(y,1))

#Get reduced PCA for each label
X_reducedclass1=X_reduced[index_class1][:]
X_reducedclass2=X_reduced[index_class2][:]

然后,我将在不同的散点图中绘制每个类别的每个PCA约简矢量

colors = ['blue',azim=110)
scatter1=ax.scatter(X_reducedclass1[:,X_reducedclass1[:,4],5],c=colors[0],cmap=plt.cm.Set1,s=40)
scatter2=ax.scatter(X_reducedclass2[:,X_reducedclass2[:,c=colors[1],s=40)

ax.set_title("Data Visualization with 3 highest variance dimensions with PCA")
ax.set_xlabel("1st eigenvector")
ax.w_xaxis.set_ticklabels([])
ax.set_ylabel("2nd eigenvector")
ax.w_yaxis.set_ticklabels([])
ax.set_zlabel("3rd eigenvector")
ax.w_zaxis.set_ticklabels([])

#ax.legend(np.unique(y))
ax.legend([scatter1,scatter2],['Empty','Full'],loc="upper right")

plt.show()

哪个给我这张美丽的照片

enter image description here

当然,这样的代码也可以使用for循环进行简化(尽管我不知道该怎么做)。

本文链接:https://www.f2er.com/3168047.html

大家都在问