仅绘制时间序列的选定点

Posted

技术标签:

【中文标题】仅绘制时间序列的选定点【英文标题】:Plot only selected points of a time series 【发布时间】:2021-11-29 06:43:43 【问题描述】:

我也有一个单变量时间序列结构:

data = [15, 5, 7, 9, 10, 23, 4, 6]

还有一个列表内的值的分数列表,结构也是如此:

score = [0.3, 0.6, 0.1, 0.8, 0.4, 0.7, 0.3, 0.1]

我也有门槛t = 0.5

据此,我创建了一个包含两列的数据框,在第一列中我有值,在第二列中我有 True 如果它是一个异常(这意味着它有一个分数分数 > t) 和 False 如果不是 (score< t)。结构是这样的:

values | anomalies
  15   |   False
  5    |   True
  7    |   False
  9    |   True
  10   |   False
  23   |   True
  4    |   False
  6    |   False

我想做的是用一种颜色绘制带有anomalies==True 的值,用另一种颜色绘制带有anomalies==False 的值。我尝试绘制正常值,然后将它们与异常值重叠,正如您在这段代码中看到的那样:

fig = plt.figure(figsize=(25,5)) 
ax1=plt.subplot(121)
sns.lineplot(data=df['values'], ax=ax1) # plot normal time series plot
sns.lineplot(data=df['values'][(df['anomalies'] == True )], color='red', ax=ax1)

但结果是下图中的那个,即使应该分开,红点也是链接在一起的:

我该如何解决?

【问题讨论】:

问题是你有点,你想为线条设置颜色。从正常点到异常点是什么颜色(和从异常点到正常点一样)? 其他点:当 score == t 时是真是假? 【参考方案1】:

您可以按照 [此处] (Highlighting arbitrary points in a matplotlib plot?) 的说明对绘图函数使用 ma​​rkevery 参数。然后您可以根据自己的喜好设置ma​​rkerface

  import pandas as pd
  import numpy as np
  import matplotlib.pyplot as plt
  import seaborn as sns
  sns.set()
  data = [15, 5, 7, 9, 10, 23, 4, 6]
  score = [0.3, 0.6, 0.1, 0.8, 0.4, 0.7, 0.3, 0.1]
  df = pd.DataFrame(data,columns=['values'])
  df['score'] = score
  plt.figure(figsize=(8,6))
  plt.plot(df.index, df['values'], '-go', markevery=np.where(df.score > 0.5, True, False), markerfacecolor='b')
  plt.xlabel('Index')
  plt.ylabel('Values')
  plt.title('Anomalies Plot')

它看起来像这样plot

您可以使用 seaborn 通过替换

获得类似的结果
plt.plot(df.index, df['values'], '-go', markevery=np.where(df.score > 0.5, True, False), markerfacecolor='b')

sns.scatterplot(x=df.index,y=df['values'], hue=df.score>0.5)
sns.lineplot(x=df.index,y=df['values'])

【讨论】:

【参考方案2】:

您可以先创建一个数据框:

df = pd.DataFrame(columns=['data','score','anomalies'])

然后:

df.loc[df[score]>t,'anomalies'] = 'True'

你的第一部分答案

【讨论】:

【参考方案3】:

使用LineCollection:

# Imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

# Data
data = [15, 5, 7, 9, 10, 23, 4, 6]
score = [0.3, 0.6, 0.1, 0.8, 0.4, 0.7, 0.3, 0.1]
t = 0.5

# Create dataframe
df = pd.DataFrame('values': data, 'score': score)
df['anomalies'] = df['score'] > t

# Build colored segments
x = zip(range(len(df)), range(1, len(df)))
y = zip(df['values'], df['values'][1:])
lines = [[(x0, x1), (y0, y1)] for (x0, y0), (x1, y1) in zip(x, y)]
linecolors = df['anomalies'].replace(True: 'red', False: 'blue')
segments = LineCollection(lines, colors=linecolors)

# Plot chart
fig, ax = plt.subplots()
ax.add_collection(segments)

# Limits are not set automatically when using LineCollection
ax.set_xlim(0, len(df))
ax.set_ylim(0, df['values'].max()+1)

输出:

>>> df
   values  score  anomalies
0      15    0.3      False
1       5    0.6       True
2       7    0.1      False
3       9    0.8       True
4      10    0.4      False
5      23    0.7       True
6       4    0.3      False
7       6    0.1      False

【讨论】:

以上是关于仅绘制时间序列的选定点的主要内容,如果未能解决你的问题,请参考以下文章

R语言绘制火山图(volcano plot)实战:为差异表达基因(DEGs)添加颜色基于显著性阈值进行点的颜色美化为选定基因添加标签

将在图表控件上绘制的点写入文本文件,但每个坐标仅一次?

如何强制 QChartView 仅绘制自身的一部分

Python循环仅绘制分类变量

OpenGL仅从顶点数组中绘制一些索引

Qwt 仅重新绘制特定区域