仅绘制时间序列的选定点
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?) 的说明对绘图函数使用 markevery 参数。然后您可以根据自己的喜好设置markerface。
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)添加颜色基于显著性阈值进行点的颜色美化为选定基因添加标签