如何在 Python 中制作交互式 PCA 散点图?

数据挖掘 Python 可视化 主成分分析 朱庇特
2021-10-09 04:14:40

matplotlib功能强大但缺乏交互性,尤其是在 Jupyter Notebook 内部。我想要一个好的离线绘图工具,比如plot.ly

4个回答

有一个很棒的库叫做MPLD3,它可以生成交互式 D3 绘图。

此代码生成与 Jupyter Notebook 兼容的流行 iris 数据集的 HTML 交互式绘图。选择画笔后,您可以选择要在所有绘图中突出显示的数据子集。选择十字箭头后,您可以将鼠标悬停在数据点上并查看有关原始数据的信息。在进行探索性数据分析时,此功能非常有用。

将 matplotlib.pyplot 导入为 plt
将 numpy 导入为 np
将熊猫导入为 pd
进口seaborn as sb
导入 mpld3
从 mpld3 导入插件
%matplotlib 内联

iris = sb.load_dataset('iris')
从 sklearn.preprocessing 导入 StandardScaler
X = pd.get_dummies(iris)
X_scal = StandardScaler().fit_transform(X)

昏暗 = 3
从 sklearn.decomposition 导入 PCA
pca = PCA(n_components = dim)
Y_sklearn = pca.fit_transform(X_scal)

# 定义一些 CSS 来控制我们的自定义标签
css = """
桌子
{
  边框折叠:折叠;
}
th
{
  颜色:#ffffff;
  背景颜色:#000000;
}
时间
{
  背景颜色:#cccccc;
}
表, th, td
{
  字体系列:Arial、Helvetica、sans-serif;
  边框:1px纯黑色;
  文本对齐:右;
}
"""

无花果,ax = plt.subplots(dim,dim, figsize=(6,6))
fig.subplots_adjust(hspace=.4, wspace=.4)
工具提示 = [无]*dim

N = 200
index = np.random.choice(范围(Y_sklearn.shape[0]),size=N)

对于范围内的 m(暗淡):
    对于范围内的 n (m+1):
        ax[m,n].grid(True, alpha=0.3)
        scatter = ax[m,n].scatter(Y_sklearn[index,m],Y_sklearn[index,n],alpha=.05)

        标签 = []
        对于索引中的 i:
            标签 = X.ix[[i], :].T.astype(int)
            label.columns = ['行 {0}'.format(X.index[i])]
            标签.append(str(label.to_html()))

        ax[m,n].set_xlabel('组件' + str(m) )
        ax[m,n].set_ylabel('组件' + str(n) )
        #ax[m,n].set_title('HTML 工具提示', size=20)

        tooltip[m] = plugins.PointHTMLTooltip(散点图,标签,
                                           voffset=20, hoffset=20, css=css)
        plugins.connect(图,工具提示[m])

plugins.connect(fig, plugins.LinkedBrush(scatter))
测试 = mpld3.fig_to_html(fig=fig)

使用 open("Output.html", "w") 作为 text_file:
    text_file.write(测试)

在我的博客上查看它的实际应用

更新 [2016 年 7 月 9 日]:我刚刚发现 Plot.ly 有离线模式,现在是开源的。它预先包装了很多花里胡哨,但在某些情况下 MPLD3 可能仍然合适。

我希望这是评论而不是答案,因为我的意图不是插入/做广告,但我目前正在研究我的论文,这可能会引起您的兴趣,因为它可以满足您的需求。实际上,它是一个聚类可视化工具,但是如果您使用 k=1 的 k-means,您将拥有一个交互式绘图,您可以在其中搜索术语、选择一个区域并查看每个节点的内容以及其他内容。看看它是否适合你!

我强烈建议改用PlotlyExpress

此代码在 iris 数据集上绘制前 3 个组件

    import plotly.express as px
    from sklearn.datasets import load_iris

    from sklearn.decomposition import PCA
    from sklearn.preprocessing import StandardScaler, FunctionTransformer
    from sklearn.pipeline import Pipeline

    X, y = load_iris(return_X_y= True)

    pca = Pipeline([("standarize", StandardScaler()), ("pca",PCA(n_components = 3)), ("dataframe", FunctionTransformer(lambda x: pd.DataFrame(x, columns = ["first_comp", "second_comp", "third_comp"])))]).fit(X)
    X3D = pca.transform(X)
    px.scatter_3d(x = "first_comp", y = "second_comp",z = "third_comp", data_frame= X3D, color= y)

在此处输入图像描述

一个非常好的选择,情节是......

就我而言,我试图根据技能绘制类似的名称,其中技能是 300 维的 word2vec 嵌入;将它带到一个 3 维向量空间,并使用 plotly Scatter3D,我能够绘制一个 3D 散点图。

和维奥拉!!得到了一个很棒的 3 维图,具有悬停和放大功能。最好的部分是它可以导出为 html 文件,使其成为适用于任何其他 PC 的即插即用,只需在浏览器中拖放(包含在下面的代码中)。

任何事情都可以变得更简单吗

from plotly.offline import plot
from plotly.graph_objs import *
import numpy as np

# x = np.random.randn(2000)
# y = np.random.randn(2000)

# Instead of simply calling plot(...), store your plot as a variable and pass it to displayHTML().
# Make sure to specify output_type='div' as a keyword argument.
# (Note that if you call displayHTML() multiple times in the same cell, only the last will take effect.)

p = plot(
  [
    Scatter3d(x=skills_df[0], y=skills_df[1], z=skills_df[2], text= skills_df['designation'], mode='markers', marker=Marker(color=skills_df['cluster_number'], size=3, opacity=0.5, colorscale='Viridis'))
  ],
  output_type='div'
#   filename='/dbfs/FileStore/tables/lnkdn_jobroles_viridis.html' turn it on to save the file
)