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

Python 绘制PCA的某些尺寸时会出现3D打印和图例,python,matplotlib,Python,Matplotlib,我通过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 fie

我通过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, dim2, 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", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **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)
plot_data-3d-pca.py:56:UserWarning:请求的投影与当前轴投影不同,使用请求的投影创建新轴。
ax=图gca(投影=3d')
plot_data-3d-pca.py:56:MatplotlibDeprecationWarning:使用与先前轴相同的参数添加轴当前将重用先前的实例。在将来的版本中,将始终创建并返回一个新实例。同时,通过向每个轴实例传递唯一的标签,可以抑制此警告,并确保将来的行为。
ax=图gca(投影=3d')
回溯(最近一次呼叫最后一次):
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/backends/backend_gtk3.py”,第307行,在idle_draw中
self.draw()
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/backends/backend_gtk3agg.py”,绘图中第76行
self.\u render\u图形(allocation.width、allocation.height)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/backends/backend_gtk3agg.py”,第20行,如图所示
后端聚合图canvasagg.draw(自)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/backends/backend_agg.py”,绘图中第388行
self.figure.draw(self.renderer)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/artist.py”,第38行,在draw_包装中
返回绘制(艺术家、渲染器、*args、**kwargs)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/figure.py”,绘图中的第1709行
渲染器、自身、艺术家、自身(合成)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/image.py”,第135行,在“绘制”列表“合成”图像中
a、 绘制(渲染器)
文件“/home/unica server/.local/lib/python3.6/site packages/matplotlib/artist.py”,第38行,在draw_包装中
返回绘制(艺术家、渲染器、*args、**kwargs)
文件“/home/unica server/.local/lib/python3.6/site packages/mpl_toolkits/mplot3d/axes3d.py”,第292行,在绘图中
反向=真):
文件“/home/unica server/.local/lib/python3.6/site packages/mpl_toolkits/mplot3d/axes3d.py”,第291行,在
key=lambda col:col.do_3d_投影(渲染器),
do_3d_投影中的文件“/home/unica server/.local/lib/python3.6/site packages/mpl_工具包/mplot3d/art3d.py”,第545行
ecs=(_zalpha(self._edgecolor3d,vzs)如果self._depthshadeelse.)
文件“/home/unica server/.local/lib/python3.6/site packages/mpl_toolkits/mplot3d/art3d.py”,第847行,位于扎尔帕
rgba=np.广播到(mcolors.到rgba数组(颜色),(透镜(Z),4))
文件“”,第6行,广播至
文件“/home/unica server/.local/lib/python3.6/site packages/numpy/lib/stride\u tricks.py”,第182行,广播至
返回(数组、形状、subok=subok、readonly=True)
文件“/home/unica server/.local/lib/python3.6/site packages/numpy/lib/stride\u tricks.py”,第127行,在广播中
op_flags=['readonly'],itershape=shape,order='C')
ValueError:操作数无法与重新映射的形状[原始->重新映射]:(0,4)和请求的形状(1,4)一起广播
我的y的形状是(8143,)而我的X_的形状是(8143,3)

我犯了什么错


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

第一个警告
请求的投影与当前轴投影不同
这是因为您试图在使用
ax=fig.gca(projection='3d')
创建轴后更改轴的投影,但您不能。将投影设置为“创建”

要修复第二个错误,请将
edgecolors='none'
替换为
edgecolors=none

下面更正的代码适用于我

#创建绘图
图=plt.图()
ax=fig.add_子图(1,1,1,projection='3d')#在创建轴时设置投影
#ax=fig.gca(projection='3d')#创建后无法更改投影
颜色=(“红色”、“灰色”)
对于zip中的数据、颜色、组(X_减少,颜色,y):
dim1、dim2、dim3=数据
#将“无”替换为“无”
最大散射(dim1、dim2、dim3、c=颜色、边色=无、标签=组)
产品名称(“Matplot 3d散点图”)
图例(y)
plt.show()
编辑:以上是我对原问题理解的答案。下面是mad自己答案的循环版本

class_值=[0,1]
标签=[“空”、“满”]
n_类=len(类值)
#分配列表
索引_类=[None]*n_类
X_减少的_类=[None]*n_类
对于i,枚举中的类i(类值):
#获取0和1标签在哪里
索引类[i]=np.where(np.isin(y,类i))
#为每个标签获得减少的PCA
X_缩减类[i]=X_缩减类[i]]
颜色=['蓝色','红色']
#更好地理解维度之间的相互作用
#绘制前三个PCA维度
图=plt.图(1,figsize=(8,6))
ax=Axes3D(图,标高=150,方位=110)
ids_plot=[0,4,5]
对于范围内的i(n_类):
#获取三个有趣的列
数据=X_减少的_类[i][:,ids_plot]
最大散点(数据[:,0],数据[:,1],数据[:,2],c=colors[i],edgecolor='k',s=40,label=labels[i])
ax.设置标题(“数据可视化,具有PCA的3个最大方差维度”)
ax.set_xlabel(“第一特征向量”)
ax.w_xaxis.set_标签([])
ax.set_ylabel(“第二特征向量”)
ax.w_yaxis.set_标签([])
ax.set_zlabel(“第三特征向量”)
ax.w_zaxis.set_标签([])
ax.图例()
plt.show()
我解决了这个问题
#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][:]
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)
scatter1=ax.scatter(X_reducedclass1[:, 0], X_reducedclass1[:, 4], X_reducedclass1[:, 5], c=colors[0], cmap=plt.cm.Set1, edgecolor='k', s=40)
scatter2=ax.scatter(X_reducedclass2[:, 0], X_reducedclass2[:, 4], X_reducedclass2[:, 5], c=colors[1], cmap=plt.cm.Set1, edgecolor='k', 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()