我正在尝试将 http://scikit-learn.org/stable/auto_examples/decomposition/plot_pca_iris.html 用于我自己的数据来构建 3D PCA 图。但是,该教程没有指定如何添加图例。另一个页面,https://matplotlib.org/users/legend_guide.html 做了,但我看不到如何将第二个教程中的信息应用到第一个。

如何修改下面的代码以添加图例?

# Code source: Gae"l Varoquaux
# License: BSD 3 clause

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import decomposition
from sklearn import datasets

np.random.seed(5)

centers = [[1, 1], [-1, -1], [1, -1]]
iris = datasets.load_iris()
X = iris.data#the floating point values
y = iris.target#unsigned integers specifying group


fig = plt.figure(1, figsize=(4, 3))
plt.clf()
ax = Axes3D(fig, rect=[0, 0, .95, 1], elev=48, azim=134)

plt.cla()
pca = decomposition.PCA(n_components=3)
pca.fit(X)
X = pca.transform(X)

for name, label in [('Setosa', 0), ('Versicolour', 1), ('Virginica', 2)]:
    ax.text3D(X[y == label, 0].mean(),
              X[y == label, 1].mean() + 1.5,
              X[y == label, 2].mean(), name,
              horizontalalignment='center',
              bbox=dict(alpha=.5, edgecolor='w', facecolor='w'))
# Reorder the labels to have colors matching the cluster results
y = np.choose(y, [1, 2, 0]).astype(np.float)
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=y, cmap=plt.cm.spectral,
           edgecolor='k')

ax.w_xaxis.set_ticklabels([])
ax.w_yaxis.set_ticklabels([])
ax.w_zaxis.set_ticklabels([])

plt.show()

最佳答案

其他答案存在一些问题,OP 和回答者似乎都不清楚;因此,这不是一个完整的答案,而是现有答案的附录。

  • spectral 颜色图已从 2.2 版的 matplotlib 中删除,
    使用 Spectralnipy_spectral 或任何 other valid colormap
  • matplotlib 中的任何颜色图的范围从 0 到 1。如果您使用该范围之外的任何值调用它,
    它只会给你最外面的颜色。要从颜色图中获取颜色,您需要对这些值进行归一化。
    这是通过 Normalize 实例完成的。在这种情况下,这是 scatter 内部的。

    因此,使用 sc = ax.scatter(...) 然后使用 sc.cmap(sc.norm(value)) 以根据散点图中使用的相同映射获取值。
    因此代码应该使用
    [sc.cmap(sc.norm(i)) for i in [1, 2, 0]]
    
  • 图例在图外。该图的大小为 4 x 3 英寸 ( figsize=(4, 3) )。
    轴的宽度占该空间的 95% ( rect=[0, 0, .95, 1] )。
    legend 的调用将图例的右中心点放置在轴宽度 = 4*0.95*1.7 = 6.46 英寸的 1.7 倍处。 ( bbox_to_anchor=(1.7,0.5) )。

    python - matplotlib : how to add legend? 中的 3D PCA-LMLPHP
    我这边的替代建议:使图形更大( figsize=(5.5, 3) ),以便图例适合,使轴仅占用图形宽度的 70%,这样图例还剩下 30%。将图例的左侧靠近坐标区边界 ( bbox_to_anchor=(1.0, .5) )。

    python - matplotlib : how to add legend? 中的 3D PCA-LMLPHP

    有关此主题的更多信息,请参阅 How to put the legend out of the plot

    您仍然在 jupyter notebook 中看到包括图例在内的完整图形的原因是 jupyter 只会将所有内容保存在 Canvas 内,即使它重叠并因此放大图形。

  • 总的来说,代码可能看起来像
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np; np.random.seed(5)
    from sklearn import decomposition, datasets
    
    centers = [[1, 1], [-1, -1], [1, -1]]
    iris = datasets.load_iris()
    X = iris.data #the floating point values
    y = iris.target #unsigned integers specifying group
    
    fig = plt.figure(figsize=(5.5, 3))
    ax = Axes3D(fig, rect=[0, 0, .7, 1], elev=48, azim=134)
    
    pca = decomposition.PCA(n_components=3)
    pca.fit(X)
    X = pca.transform(X)
    
    labelTups = [('Setosa', 0), ('Versicolour', 1), ('Virginica', 2)]
    for name, label in labelTups:
        ax.text3D(X[y == label, 0].mean(),
                  X[y == label, 1].mean() + 1.5,
                  X[y == label, 2].mean(), name,
                  horizontalalignment='center',
                  bbox=dict(alpha=.5, edgecolor='w', facecolor='w'))
    # Reorder the labels to have colors matching the cluster results
    y = np.choose(y, [1, 2, 0]).astype(np.float)
    sc = ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=y, cmap="Spectral", edgecolor='k')
    
    ax.w_xaxis.set_ticklabels([])
    ax.w_yaxis.set_ticklabels([])
    ax.w_zaxis.set_ticklabels([])
    
    colors = [sc.cmap(sc.norm(i)) for i in [1, 2, 0]]
    custom_lines = [plt.Line2D([],[], ls="", marker='.',
                    mec='k', mfc=c, mew=.1, ms=20) for c in colors]
    ax.legend(custom_lines, [lt[0] for lt in labelTups],
              loc='center left', bbox_to_anchor=(1.0, .5))
    
    plt.show()
    

    并生产

    python - matplotlib : how to add legend? 中的 3D PCA-LMLPHP

    关于python - matplotlib : how to add legend? 中的 3D PCA,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49564844/

    10-12 21:51