Plotly 注释彼此太近(不可读)

Posted

技术标签:

【中文标题】Plotly 注释彼此太近(不可读)【英文标题】:Plotly annotations too close to each other (not readable) 【发布时间】:2021-09-27 21:50:00 【问题描述】:

我有以下代码为 PCA 之后的载荷创建图:

# Creating pipeline objects 
## PCA
pca = PCA(n_components=2)
## Create columntransformer to only scale a selected set of featues
categorical_ix = X.select_dtypes(exclude=np.number).columns

features = X.columns

ct = ColumnTransformer([
        ('encoder', OneHotEncoder(), categorical_ix),
        ('scaler', StandardScaler(), ['tenure', 'MonthlyCharges', 'TotalCharges'])
    ], remainder='passthrough')

# Create pipeline
pca_pipe = make_pipeline(ct,
                         pca)

# Fit data to pipeline
pca_result = pca_pipe.fit_transform(X)

loadings = pca.components_.T * np.sqrt(pca.explained_variance_)

fig = px.scatter(pca_result, x=0, y=1, color=customer_data_raw['Churn'])

for i, feature in enumerate(features):
    fig.add_shape(
        type='line',
        x0=0, y0=0,
        x1=loadings[i, 0],
        y1=loadings[i, 1]
    )
    fig.add_annotation(
        x=loadings[i, 0],
        y=loadings[i, 1],
        ax=0, ay=0,
        xanchor="center",
        yanchor="bottom",
        text=feature,
    )
fig.show()

产生以下输出:

如何使装载的标签可读?

编辑: X中有19个特征。

    gender  SeniorCitizen   Partner Dependents  tenure  PhoneService    MultipleLines   InternetService OnlineSecurity  OnlineBackup    DeviceProtection    TechSupport StreamingTV StreamingMovies Contract    PaperlessBilling    PaymentMethod   MonthlyCharges  TotalCharges
customerID                                                                          
7590-VHVEG  Female  0   Yes No  1   No  No phone service    DSL No  Yes No  No  No  No  Month-to-month  Yes Electronic check    29.85   29.85
5575-GNVDE  Male    0   No  No  34  Yes No  DSL Yes No  Yes No  No  No  One year    No  Mailed check    56.95   1889.50
3668-QPYBK  Male    0   No  No  2   Yes No  DSL Yes Yes No  No  No  No  Month-to-month  Yes Mailed check    53.85   108.15
7795-CFOCW  Male    0   No  No  45  No  No phone service    DSL Yes No  Yes Yes No  No  One year    No  Bank transfer (automatic)   42.30   1840.75
9237-HQITU  Female  0   No  No  2   Yes No  Fiber optic No  No  No  No  No  No  Month-to-month  Yes Electronic check    70.70   151.65

【问题讨论】:

你可以把箭头加长,但是有多少个注解呢? X 看起来像什么,列是什么?您可以将此信息添加到问题中吗? 谢谢!刚刚添加了相应的信息。但是,数据框将无法正确显示。 哦,这不是问题,感谢您更新您的问题!这应该可以帮助人们更好地理解和诊断您的问题 非常感谢我的朋友!! 我很高兴听到我的代码有帮助!我很好奇最终结果是什么样子的——如果注释现在是分开的,你介意将绘图的屏幕截图上传到你的问题中吗?这也将帮助有类似问题的任何人了解我的解决方案是什么样的,以便他们决定是否要遵循我概述的方法 【参考方案1】:

根据您的 DataFrame,您有 19 个要素,并且您将它们全部添加到该位置作为您的线,因为 ax 和 ay 都设置为 0。

当您循环遍历要旋转的特征时,我们可以更改 axay,这有望使您的注释更加可区分。这是基于使用 x = r*cos(theta)y = r*sin(theta) 从极坐标转换为笛卡尔坐标,其中 theta 通过值 0*360/19, 1*360/19, ... , 18*360/19。我们希望将 x 和 y 参考设置为 x 和 y 坐标而不是纸张坐标,然后设置 r=2 或与您的绘图相当的某个值(这将使注释线的长度最长为 2)

from math import sin, cos, pi
r = 2 # this can be modified as needed, and is in units of the axis
theta = 2*pi/len(features)

for i, feature in enumerate(features):
    fig.add_shape(
        type='line',
        x0=0, y0=0,
        x1=loadings[i, 0],
        y1=loadings[i, 1]
    )
    fig.add_annotation(
        x=loadings[i, 0],
        y=loadings[i, 1],
        ax=r*sin(i*theta), 
        ay=r*cos(i*theta),
        axref="x",
        ayref="y",
        xanchor="center",
        yanchor="bottom",
        text=feature,
    )

【讨论】:

以上是关于Plotly 注释彼此太近(不可读)的主要内容,如果未能解决你的问题,请参考以下文章

Plotly:如何在 Plotly Express 中注释多行?

Plotly 3D 绘图注释

plotly::subplot 注释标题在 R Shiny 中消失

Plotly 注释文本:在 URL 中编码哈希 (#) 字符

Plotly 图形组件不能接受视口单位来设置文本注释字体大小

当我在 plotly 中使用 ggplotly 函数时,为啥文本注释会丢失?