You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为matplotlib散点图创建与绘图颜色匹配的准确图例

问题根源

你的代码存在两个明显错误,直接导致图例匹配失效:

  1. 无意义的循环:你在for i in range(clusters)里重复调用了4次scatter,每次传入的都是完整的坐标数组和标签数组,相当于同一批点被叠绘了4次。matplotlib收集图例项时会把坐标轴参考线、所有叠绘的散点层都纳入统计,根本不会按聚类标签做归类。
  2. 图例传参错误:你直接把全量my_labels列表传给legend(),matplotlib只会拿列表前N个值,按顺序匹配当前轴上已有的前N个绘图对象,完全不会建立「颜色-聚类标签」的对应关系。
修正方法

推荐两种写法,都能实现颜色和图例一一对应的效果:

方法1:按聚类分组绘制(逻辑直观,易自定义)

去掉无效的叠绘循环,按聚类标签筛选点后单独绘制每个聚类的散点,绘制时直接给每个聚类指定图例标签即可:

import matplotlib.pyplot as plt
import numpy as np

clusters = 4
two_d_matrix = np.array([[0.00617068, -0.53451777], [-0.01837677, -0.47131886], ...])
my_labels = np.array([0, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3])
cmap = plt.get_cmap('viridis', clusters)

fig, (plot1, plot2) = plt.subplots(1, 2, sharex=False, sharey=False, figsize=(20, 10))

# 绘制第一个子图
plot1.axhline(0, color='#afafaf')
plot1.axvline(0, color='#afafaf')
for cluster_id in range(clusters):
    cluster_mask = my_labels == cluster_id
    plot1.scatter(
        two_d_matrix[cluster_mask, 0], 
        two_d_matrix[cluster_mask, 1],
        s=30, 
        color=cmap(cluster_id), 
        label=f'Cluster {cluster_id}'
    )
plot1.legend(title="聚类")
plot1.set_title("My First Plot")

# 绘制第二个子图
plot2.axhline(0, color='#afafaf')
plot2.axvline(0, color='#afafaf')
for cluster_id in range(clusters):
    cluster_mask = my_labels == cluster_id
    plot2.scatter(
        two_d_matrix[cluster_mask, 0], 
        two_d_matrix[cluster_mask, 1],
        s=30, 
        color=cmap(cluster_id), 
        label=f'Cluster {cluster_id}'
    )
plot2.legend(title="聚类")
plot2.set_title("My Second Plot")

plt.show()

方法2:单次绘制+自动生成图例(代码更简洁)

不需要循环筛选点,只调用一次scatter传入全部点和标签,利用matplotlib自带的legend_elements()方法自动生成和颜色映射匹配的图例项:

# 以第一个子图为例,替换原来的循环scatter部分
plot1.axhline(0, color='#afafaf')
plot1.axvline(0, color='#afafaf')
scatter1 = plot1.scatter(
    two_d_matrix[:, 0], 
    two_d_matrix[:, 1], 
    s=30, 
    c=my_labels, 
    cmap='viridis'
)
plot1.legend(handles=scatter1.legend_elements()[0], labels=list(range(clusters)), title="聚类")

这种写法不会重复叠绘点,也不会把坐标轴参考线纳入图例,生成的图例条目和散点颜色完全对应。


内容的提问来源于stack exchange,提问作者AdeDoyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 21:27:34