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

如何让Matplotlib标记所有异常值为不同颜色而非仅一个

解决散点图异常值标记问题

我帮你找出代码里的问题啦,你现在只显示一个异常值的核心原因是异常值筛选的逻辑错误,下面一步步给你分析和修正:

问题分析

你原来的异常值筛选代码outliers = normed[normed>2*std_dev]有两个关键问题:

  1. 这个判断是逐元素比较,会把所有大于2倍标准差的单个元素提取出来,变成一个一维数组,而不是保留完整的样本行结构
  2. 异常值的定义应该是“样本的某个特征与该特征的均值偏差超过2个标准差”,你没有考虑到绝对值(毕竟偏离可以是正向也可以是负向),而且没有筛选出完整的异常样本

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 读取数据
data = pd.read_csv('1fXr31hcEemkYxLyQ1aU1g_50fc36ee697c4b158fe26ade3ec3bc24_Banknote-authentication-dataset- (1).csv')
data = np.array(data)

# 归一化处理
min_vals = np.min(data, 0)
max_vals = np.max(data, 0)
normed = (data - min_vals) / (max_vals - min_vals)

# 计算归一化后数据的均值和标准差(按列计算)
normed_mean = np.mean(normed, 0)
normed_std = np.std(normed, 0)

# 创建画布和绘图对象
fig, graph = plt.subplots()

# 绘制基础散点图
graph.scatter(normed[:,0], normed[:,1], label='Normal Data')

# 绘制均值点
graph.scatter(normed_mean[0], normed_mean[1], c='green', marker='*', s=100, label='Mean')

# 筛选异常值:判断每个样本的第0列或第1列是否偏离均值超过2倍标准差
# 这里取绝对值,覆盖正向和负向的偏离
outlier_mask_0 = np.abs(normed[:,0] - normed_mean[0]) > 2 * normed_std[0]
outlier_mask_1 = np.abs(normed[:,1] - normed_mean[1]) > 2 * normed_std[1]
# 只要任意一个维度是异常,就标记为异常样本
outlier_mask = outlier_mask_0 | outlier_mask_1
outliers = normed[outlier_mask]

# 绘制异常值点
graph.scatter(outliers[:,0], outliers[:,1], c='red', marker='x', s=80, label='Outliers')

# 添加图例和标题,让图表更清晰
graph.legend()
graph.set_xlabel('Feature 0 (Normalized)')
graph.set_ylabel('Feature 1 (Normalized)')
graph.set_title('Scatter Plot with Outliers Marked')

plt.show()

关键修正点说明

  • 变量名优化:把min、max改成min_vals、max_vals,避免覆盖Python内置函数
  • 异常值筛选逻辑:用掩码(mask)筛选出完整的异常样本行,而不是单个元素,同时加入绝对值判断负向偏离的情况
  • 可视化优化:添加了图例、坐标轴标签和标题,让图表更易读,用不同的标记区分均值和异常值

这样修改后,所有符合你定义的异常值都会被标记成红色叉号啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:48:56