在散点图上标记离群值

问题描述 投票:2回答:3

我有一个看起来如下的数据框:

 print(df.head(10))

 day         CO2
   1  549.500000
   2  663.541667
   3  830.416667
   4  799.695652
   5  813.850000
   6  769.583333
   7  681.941176
   8  653.333333
   9  845.666667
  10  436.086957

然后,我使用以下函数和代码行从CO2列中获取ouliers:

def estimate_gaussian(dataset):

    mu = np.mean(dataset)#moyenne cf mu
    sigma = np.std(dataset)#écart_type/standard deviation
    limit = sigma * 1.5

    min_threshold = mu - limit
    max_threshold = mu + limit

    return mu, sigma, min_threshold, max_threshold

mu, sigma, min_threshold, max_threshold = estimate_gaussian(df['CO2'].values)


condition1 = (dataset < min_threshold)
condition2 = (dataset > max_threshold)

outliers1 = np.extract(condition1, dataset)
outliers2 = np.extract(condition2, dataset)

outliers = np.concatenate((outliers1, outliers2), axis=0)

哪个给我以下结果:

print(outliers)

[830.41666667 799.69565217 813.85       769.58333333 845.66666667]

现在,我想在散点图中用红色标记那些离群值。

您可以找到下面我到目前为止在散点图中用红色标记一个异常值的代码,但是我找不到一种方法可以对异常值列表的每个元素(numpy.ndarray:numpy.ndarray :)进行处理。

y = df['CO2']

x = df['day']

col = np.where(x<0,'k',np.where(y<845.66666667,'b','r'))

plt.scatter(x, y, c=col, s=5, linewidth=3)
plt.show()

这是我得到的,但我希望所有油烟机都得到相同的结果。您能帮我吗?

https://ibb.co/Ns9V7Zz

python matplotlib plot scatter-plot outliers
3个回答
0
投票

您可以创建一个附加列(布尔值),在其中定义点是否为异常值(真)或(异常),然后使用两个散点图:

df["outlier"] = # your boolean np array goes in here
plt.scatter[df.loc[df["outlier"], "day"], df.loc[df["outlier"], "CO2"], color="k"]
plt.scatter[df.loc[~df["outlier"], "day"], df.loc[~df["outlier"], "CO2"], color="r"]

0
投票

可能不是最有效的解决方案,但是我觉得多次调用plt.scatter更容易,每次都传递一个xy对。由于我们从不调用新图形(例如,使用plt.figure()),因此每个xy对都绘制在同一图形上。

然后,在每次迭代中,我们只需要检查y值是否是离群值即可。如果是,我们在color调用中更改plt.scatter关键字参数。

尝试一下:

mu, sigma, min_threshold, max_threshold = estimate_gaussian(df['CO2'].values)

xs = df['day']
ys = df['CO2']

for x, y in zip(xs, ys):
    color = 'blue'  # non-outlier color
    if not min_threshold <= y <= max_threshold:  # condition for being an outlier
        color = 'red'  # outlier color
    plt.scatter(x, y, color=color)
plt.show()

0
投票

我不确定您的col列表背后的想法是什么,但是您可以将col替换为

col = ['red' if xx in list(outliers) else 'blue' for xx in x] 

0
投票

有几种方法,根据您的条件创建一系列颜色并将其传递给c参数。

df = pd.DataFrame({'CO2': {0: 549.5,
  1: 663.54166699999996,
  2: 830.41666699999996,
  3: 799.695652,
  4: 813.85000000000002,
  5: 769.58333300000004,
  6: 681.94117599999993,
  7: 653.33333300000004,
  8: 845.66666699999996,
  9: 436.08695700000004},
 'day': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}})

In [11]: colors = ['r' if n<750 else 'b' for n in df['CO2']]

In [12]: colors
Out[12]: ['r', 'r', 'b', 'b', 'b', 'b', 'r', 'r', 'b', 'r']

In [13]: plt.scatter(df['day'],df['CO2'],c=colors)
© www.soinside.com 2019 - 2024. All rights reserved.