You need to enable JavaScript to run this app. Plotly绘制PCA载荷图标注重叠无法阅读 如何调整提升可读性
优惠活动
大模型
产品
解决方案
定价
更多

Plotly绘制PCA载荷图标注重叠无法阅读 如何调整提升可读性

解决PCA载荷散点图标注重叠的方案

前置修正:解决特征与载荷的匹配错误

你当前的代码存在索引错配问题:你对分类特征做了独热编码,编码后特征维度会远高于原始的19个,直接用原始X的特征名对应编码后的载荷属于逻辑错误,首先需要正确获取编码后的所有特征名:

# 拟合pipeline后获取编码后的完整特征名
encoded_features = pca_pipe.named_steps['columntransformer'].get_feature_names_out()
loadings = pca.components_.T * np.sqrt(pca.explained_variance_)

标注防重叠核心优化点

  • 放大画布尺寸,给标签留出足够展示空间
  • 对载荷端点做小幅外移,避免标签和载荷线重叠
  • 给标签添加半透明白色背景,降低互相遮挡的影响
  • 根据载荷方向动态调整标签锚点和角度,提升可读性
  • (可选)仅展示载荷模长排名前N的特征,减少标签总量

修改后的完整可运行代码

import numpy as np
import plotly.express as px
from sklearn.decomposition import PCA
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import make_pipeline

# 原有pipeline逻辑不变
categorical_ix = X.select_dtypes(exclude=np.number).columns
ct = ColumnTransformer([
        ('encoder', OneHotEncoder(), categorical_ix),
        ('scaler', StandardScaler(), ['tenure', 'MonthlyCharges', 'TotalCharges'])
    ], remainder='passthrough')
pca_pipe = make_pipeline(ct, PCA(n_components=2))
pca_result = pca_pipe.fit_transform(X)

# 修正:获取编码后的正确特征名
pca = pca_pipe.named_steps['pca']
encoded_features = pca_pipe.named_steps['columntransformer'].get_feature_names_out()
loadings = pca.components_.T * np.sqrt(pca.explained_variance_)

# 放大画布尺寸
fig = px.scatter(pca_result, x=0, y=1, color=customer_data_raw['Churn'],
                 width=1000, height=800)

# 载荷缩放系数,可根据实际载荷大小调整,拉大特征间距
load_scale = 3

for i, feature in enumerate(encoded_features):
    x1, y1 = loadings[i, 0] * load_scale, loadings[i, 1] * load_scale
    # 绘制载荷线
    fig.add_shape(
        type='line',
        x0=0, y0=0,
        x1=x1, y1=y1,
        line=dict(color='red', width=1)
    )
    # 计算标签角度,顺着载荷线方向
    angle = np.arctan2(y1, x1) * 180 / np.pi
    # 根据象限调整锚点,避免标签压在线上
    xanchor = 'left' if x1 > 0 else 'right'
    yanchor = 'bottom' if y1 > 0 else 'top'
    
    fig.add_annotation(
        x=x1,
        y=y1,
        text=feature,
        showarrow=False,
        xanchor=xanchor,
        yanchor=yanchor,
        textangle=angle if abs(angle) < 90 else angle + 180, # 保证文字正向可读
        font=dict(size=9),
        bgcolor='rgba(255,255,255,0.7)', # 半透明白色背景降低遮挡
        borderpad=2
    )

# 开启全局防重叠配置
fig.update_layout(
    uniformtext_minsize=8,
    uniformtext_mode='show',
    xaxis_title='PC1',
    yaxis_title='PC2'
)
fig.show()

如果标签还是较多,可在循环前添加过滤逻辑,仅保留载荷模长最大的前15个特征标注:

# 计算每个特征的载荷模长
loading_magnitude = np.linalg.norm(loadings, axis=1)
# 取模长前15的特征索引,数字可按需调整
top_idx = loading_magnitude.argsort()[-15:]
# 循环仅遍历top_idx即可
for i in top_idx:
    feature = encoded_features[i]
    # 剩余绘制逻辑和上文一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 22:39:01