基于类别的 colors/label 不同的 Matplotlib 散点图

Matplotlib scatter plot with different colors/label based on a category

给定一个 2d data,在 space 中有 n 个点。以及大小为 'k < n' 的类别列表和每个 data 点的类别标签列表(当然具有与 data 相同的维度,即大小 n)。是否可以绘制散点图并在图例框上显示没有 n 个不同条目的图例?

数据如下所示:

categories = {'fruit': 0, 'animal': 1}
data = np.array([ [1,1], [2,1], [0,1], [3,2], [3,3] ])
labels = [ 'fruit', 'fruit', 'animal', 'animal', 'fruit' ]

还有一个片段来展示我的尝试

color_categories = [f'C{categories[l]}' for l in labels]
plt.scatter(data[:,0], data[:,1], c=[f'C{categories[l]}' for l in labels], label=labels)
plt.legend();

使用图例上方的代码显示列表,而不是每个类别。我可以在类别中使用 for 循环并应用一些“过滤”来达到可接受的解决方案,如:

for k, v in categories.items():
    positions = [ i for i in range(len(labels)) if labels[i] == k ]
    points_to_plot = np.take(data, positions, axis=0)
    plt.scatter(points_to_plot[:,0], points_to_plot[:,1], label=k)
plt.legend()

但我真的不喜欢这种方式。有没有更直接的方法来处理这个问题?

你可以使用 seaborn:

import seaborn as sns
import numpy as np

data = np.array([[1,1], [2,1], [0,1], [3,2], [3,3]])
labels = ['fruit', 'fruit', 'animal', 'animal', 'fruit']
sns.scatterplot(x=data[:, 0], y=data[:, 1], hue=labels)

它给出:

这是一个仅使用 matplotlib 的解决方案(和 numpy,因为这是您用来定义原始数据集的内容)。基本上,将所有类别组成一组,然后分别拉取和绘制满足每个类别的数据。

import numpy as np
import matplotlib.pyplot as plt

data = np.array([ [1,1], [2,1], [0,1], [3,2], [3,3] ])
labels = [ 'fruit', 'fruit', 'animal', 'animal', 'fruit' ]

for l in set(labels):
    x = [data[i][0] for i in range(len(data)) if labels[i] == l]
    y = [data[i][1] for i in range(len(data)) if labels[i] == l]
    plt.plot(x,y,'o',label = l)
    # alternately, 
    #plt.scatter(x,y,label = l)

plt.legend()

如果您希望图例按字母顺序排列,您可以将 for 循环更改为:

for l in sorted(set(labels)):