Skip to main content
 首页 » 编程设计

python之Matplotlib:3D 散点图无法识别标签

2025年05月04日11sxdcgaq8080

我相信之前有人问过与此类似的问题,但它并没有真正为我澄清问题。

基本上,我有一个元组列表,每个元组都充当一个点(例如 (x, y, z))。

我想在运行聚类算法(对点进行颜色编码)后以 2D 或 3D 方式绘制它们。

clusters = [] 
def plotPoints(self): 
    fig = plt.figure() 
    if self.clusters[0].dimensions == 2: 
        ax = fig.add_subplot(111) 
        for i in range(0, len(self.clusters)): 
            ax.scatter(*zip(*self.clusters[i].points), c=self.clusters[i].color, marker="o", label=("Cluster " + str(i + 1))) 
        plt.legend(loc='upper left') 
        plt.show() 
    elif self.clusters[0].dimensions == 3: 
        ax = fig.add_subplot(111, projection='3d') 
        for i in range(0, len(self.clusters)): 
            ax.scatter(*zip(*self.clusters[i].points), c=self.clusters[i].color, marker="o", label=("Cluster " + str(i + 1))) 
        plt.legend(loc='upper left') 
        plt.show() 
    else: 
        print "Cannot plot in dimensions lower than 2 or higher than 3" 

集群类:

class Cluster(object): 
centroid = () 
dimensions = 0 
color = 'k' 
 
def __init__(self, init_pt, color): 
    self.points = [] 
    self.points.append(init_pt) 
    self.dimensions = len(init_pt) 
    self.centroid = init_pt 
    self.color = color 
 
def addPoint(self, pt): 
    try: 
        if len(pt) != self.dimensions: 
            raise ArithmeticError("Wrong number of dimensions on new point, ignoring") 
        else: 
            centroid_dim_list = [] 
            for dim in range(0, self.dimensions): 
                centroid_dim_list.append((self.centroid[dim] * len(self.points) + pt[dim]) / float(len(self.points) + 1)) 
            self.centroid = tuple(centroid_dim_list) 
            self.points.append(pt) 
    except ArithmeticError as ae: 
        print ae.message 
        pass 

2D 绘图工作得很好(而且看起来非常好),但 3D 绘图给我一个警告:

UserWarning: No labeled objects found. Use label='...' kwarg on individual plots. 
  warnings.warn("No labeled objects found. " 

并且没有图例出现。但是我正在标记要点,并且我使用的代码几乎相同,所以我对问题出在哪里感到困惑。我听说过代理对象,但我不知道如何在这种情况下使用它。

请您参考如下方法:

我通过添加以下代码部分解决了我的问题:

ax.plot([], [], 'o', c=self.clusters[i].color, label="Cluster " + str(i + 1)) 

对循环的每一次迭代,给出下图。

标记由于某种原因加倍了,但至少它在大多数情况下是有效的。如果有人可以评论为什么它加倍,那就太好了。

编辑 根据 jedwards 的评论,我通过将 legend() 调用更改为:

plt.legend(numpoints=1 , loc='upper left')