如何让Matplotlib散点图图例不依赖点颜色并关联编号与名称
解决方法
核心思路
保留聚类分组的点颜色,同时替换原有聚类图例为点编号-对应名称的自定义图例,每个图例条目的颜色与对应点的聚类颜色一致。
完整代码示例
import matplotlib.pyplot as plt from matplotlib.lines import Line2D import pandas as pd import numpy as np # 示例数据集(替换成你的真实数据) df = pd.DataFrame({ 'x': np.random.rand(10), 'y': np.random.rand(10), 'cluster': np.random.randint(0, 3, 10), 'point_id': range(1, 11), 'names': [f'name_{i}' for i in range(1, 11)] }) # 固定聚类颜色映射,确保同组点颜色一致 cmap = plt.get_cmap('viridis') norm = plt.Normalize(df['cluster'].min(), df['cluster'].max()) # 绘制散点图,按聚类分配颜色 scatter = plt.scatter(df['x'], df['y'], c=df['cluster'], cmap=cmap, norm=norm) # 保留点编号标注(原有逻辑) for idx, row in df.iterrows(): plt.text(row['x'], row['y'], str(row['point_id']), ha='center', va='bottom', fontsize=9) # 构建自定义图例元素 legend_elements = [] for _, row in df.iterrows(): # 获取当前点的聚类颜色 point_color = cmap(norm(row['cluster'])) # 创建与散点样式匹配的图例标记 elem = Line2D([0], [0], marker='o', color='w', markerfacecolor=point_color, markersize=10, label=f"{row['point_id']} - '{row['names']}'") legend_elements.append(elem) # 添加自定义图例,调整位置避免遮挡 plt.legend(handles=legend_elements, title='Point Info', bbox_to_anchor=(1.05, 1), loc='upper left') # 图表基础设置 plt.xlabel('X轴') plt.ylabel('Y轴') plt.title('带自定义图例的聚类散点图') plt.tight_layout() plt.show()
关键步骤说明
- 固定颜色映射:用
cmap和norm确保同一聚类分组的点颜色统一,避免颜色随机变化。 - 保留点编号标注:沿用原有循环逻辑,为每个点标注编号。
- 自定义图例:遍历每个数据行,创建对应图例条目——颜色取该点的聚类颜色,标签格式为
点编号 - '名称',最后通过handles参数替换原有聚类图例。 - 图例优化:通过
bbox_to_anchor把图例放在图表外侧,避免遮挡数据点;若点数量多,可添加ncol=2参数分栏显示图例。
内容的提问来源于stack exchange,提问作者Wiktoria
相关产品推荐
相关产品推荐

