如何用Python Plotly绘制带主成分方向向量的3D Biplot
在Plotly Python中绘制3D PCA Biplot的方向向量
我完全懂你想实现的效果——把R里的3D Biplot搬到Plotly Python里,核心就是要画出那些红色的主成分方向向量对吧?我之前也试过把R的代码转成Python,踩过几个坑,给你一套能直接跑的完整方案:
步骤1:准备工具与数据
首先导入需要的库,我们用sklearn做PCA,Plotly画3D图,用经典的鸢尾花数据集做示例(你可以替换成自己的数据):
import numpy as np import pandas as pd from sklearn.decomposition import PCA from sklearn.datasets import load_iris import plotly.graph_objects as go
加载并预处理数据:
# 加载鸢尾花数据集 iris = load_iris() X = iris.data feature_names = iris.feature_names target_names = iris.target_names # 做PCA降维到3个主成分 pca = PCA(n_components=3) X_pca = pca.fit_transform(X)
步骤2:处理主成分方向向量(关键!)
主成分的方向向量其实就是PCA模型里的components_属性,不过它是单位向量,直接画的话会非常短,几乎看不见。我们需要用主成分的标准差来缩放这些向量,让它们的长度和数据分布匹配:
# 提取特征向量(方向向量)和主成分的标准差 components = pca.components_ std_dev = pca.explained_variance_ ** 0.5 # 缩放向量:用标准差乘以特征向量,让向量长度和数据尺度匹配 scaled_components = components * std_dev[:, np.newaxis]
步骤3:用Plotly绘制3D Biplot
先画样本点的3D散点图,然后逐个添加红色的方向向量,最后加上标签:
# 创建图表对象 fig = go.Figure() # 1. 添加样本点的3D散点 for target, color in zip(range(3), ['blue', 'green', 'purple']): mask = iris.target == target fig.add_trace(go.Scatter3d( x=X_pca[mask, 0], y=X_pca[mask, 1], z=X_pca[mask, 2], mode='markers', marker=dict(size=5, color=color), name=target_names[target] )) # 2. 添加红色的主成分方向向量 for i in range(len(feature_names)): # 向量从原点(0,0,0)出发,到缩放后的分量位置 fig.add_trace(go.Scatter3d( x=[0, scaled_components[0, i]], y=[0, scaled_components[1, i]], z=[0, scaled_components[2, i]], mode='lines+text', line=dict(color='red', width=3), text=[None, feature_names[i]], # 只在向量终点加标签 textposition='top center' )) # 设置布局 fig.update_layout( title='3D PCA Biplot with Direction Vectors', scene=dict( xaxis_title=f'PC1 ({pca.explained_variance_ratio_[0]:.1%})', yaxis_title=f'PC2 ({pca.explained_variance_ratio_[1]:.1%})', zaxis_title=f'PC3 ({pca.explained_variance_ratio_[2]:.1%})', camera=dict(eye=dict(x=1.5, y=1.5, z=1)) # 调整视角让向量更清晰 ), showlegend=True ) # 显示图表 fig.show()
关键细节说明
- 向量缩放:为什么要用
std_dev?因为主成分的标准差反映了该维度上数据的离散程度,用它缩放单位向量后,向量的长度能直观体现原始特征对主成分的贡献大小。 - 向量绘制:用
Scatter3d的lines模式,每个向量都是从原点到scaled_components对应的坐标点,颜色设为红色突出显示。 - 标签位置:把特征名称放在向量的终点,方便对应到向量方向。
你可以直接把这段代码跑起来,然后替换成你自己的数据集和特征名称就行,完全不需要依赖R的代码逻辑,纯Python实现~
内容的提问来源于stack exchange,提问作者Fenil
相关产品推荐
相关产品推荐

