绘制散点图中的PCA输出,同时根据标签python matplotlib进行着色

时间:2017-07-26 17:27:03

标签: python matplotlib pca

我刚刚完成了14个变量的PCA分析,我选择这些变量压缩成2个组件。

pca = PCA(n_components=2)
pca.fit(z)
a = pca.fit_transform(z)

这给出的输出形式为:

[[ -3.84514275e+00  -1.19829226e-01]
 [ -4.78476227e+00  -1.35986090e-01]
 [ -2.26702900e+00  -1.19665853e+00]
 [ -5.01021616e+00   2.76005130e+00]
 [ -5.57580326e+00  -2.00656680e+00]
 [ -5.08184415e+00  -3.68721491e+00]
 [ -3.41505366e+00  -7.61184868e-01]
 [ -4.92439159e+00  -1.82147509e+00]
...
 [ -3.34931300e+00   7.57884906e-01]]

我想做以下事情:

  1. 在散点图上绘制每个观察点,其中PC1(x)是每个数组中的第一个值,PC2(y)是第二个值。

  2. 根据初始的PCA前数据,根据相应的标签类型(即A =红色,B =蓝色,C =绿色等)为每个观察颜色着色。

  3. 使用初始PCA前数据(即John,Peter,Sally等)的观察名称标记SELECTED(非ALL)观察结果

  4. 任何/所有这些问题都非常感谢任何帮助。

    值得注意的是我试图通过以下方式进行分散:

    plt.scatter(a[1], a[2])
    plt.show()
    

    但显然这不起作用,因为我的输出不是用逗号分隔的,只能绘制2个点。无法帮助我解决它,所以会欣赏SO的意见。

    编辑:

    表格中的数据集:

    John, A, var1, var2, var3, ..., var14
    Peter, A, var1, var2, var3, ..., var14
    Sally, B, var1, var2, var3, ..., var14
    Cath, C, var1, var2, var3, ..., var14
    Jim, A, var1, var2, var3, ..., var14
    

    我正在做类似的事情:

    enter image description here

1 个答案:

答案 0 :(得分:2)

我认为您的问题现在非常明确 - 感谢编辑!

这里是如何创建您描述的情节。

首先,让我们生成一些示例数据:

# Params
n_samples  = 100
m_features =  14
selected_names = ['name_13', 'name_23', 'name_42', 'name_66']

# Generate
np.random.seed(42)
names    = ['name_%i' % i for i in range(n_samples)]
labels   = [np.random.choice(['A','B','C','D']) for i in range(n_samples)]
features = np.random.random((n_samples,m_features))

接下来我们做PCA:

pca = PCA(n_components=2)
features_pca = pca.fit_transform(features)

然后我们准备一个长度为n的列表/数组,将标签A,B,C,...转换为颜色。这些可以是手工选择的颜色......

# Label to color dict (manual)
label_color_dict = {'A':'red','B':'green','C':'blue','D':'magenta'}

# Color vector creation
cvec = [label_color_dict[label] for label in labels]

...或只是一系列整数。

# Label to color dict (automatic)
label_color_dict = {label:idx for idx,label in enumerate(np.unique(labels))}

# Color vector creation
cvec = [label_color_dict[label] for label in labels]

最后,是时候策划了。

# Create the scatter plot
plt.figure(figsize=(8,8))
plt.scatter(features_pca[:,0], features_pca[:,1],
            c=cvec, edgecolor='', alpha=0.5)

# Add the labels
for name in selected_names:

    # Get the index of the name
    i = names.index(name)

    # Add the text label
    labelpad = 0.01   # Adjust this based on your dataset
    plt.text(features_pca[i,0]+labelpad, features_pca[i,1]+labelpad, name, fontsize=9)

    # Mark the labeled observations with a star marker
    plt.scatter(features_pca[i,0], features_pca[i,1],
                c=cvec[i], vmin=min(cvec), vmax=max(cvec),
                edgecolor='', marker='*', s=100)

# Add the axis labels
plt.xlabel('PC 1 (%.2f%%)' % (pca.explained_variance_ratio_[0]*100))
plt.ylabel('PC 2 (%.2f%%)' % (pca.explained_variance_ratio_[1]*100)) 

# Done
plt.show()

如您所见,可以通过plt.scatter kwarg将不同的颜色输入c。此外,我建议edgecolor='',因为这通常看起来更清晰。您可以使用alpha来增加/减少透明度,这会使标记点更多/更少。

使用plt.text和适当的x和y位置简单地将标签放置在绘图上,我在这里稍微调整一下(使用labelpad),以便标签很好地定位在旁边标记

对于星标,请注意vminvmax在使用数字颜色矢量时很重要,否则星星会以错误的颜色结束。

这是结果(使用手动定义的颜色):

enter image description here