基于类别的 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)):
给定一个 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)):