如何循环多个axvspan阴影进行重复事件?

时间:2019-05-29 02:20:39

标签: matplotlib time-series seaborn

我正在尝试在同一图上循环2个时间序列,并将收集它们的条件标记为axvspan块。 数据看起来像这样:

    time    seriesA sereiesB    Condition
0.00    10  2   A
0.12    4   20  A
0.24    14  16  A
0.36    5   16  A
0.48    8   13  A
0.6     5   16  B
0.72    17  3   B
0.84    8   20  B
0.96    3   3   B
1.08    18  20  C
1.20    11  13  C
1.32    8   10  C
1.44    17  11  A
1.56    15  2   A
1.68    1   1   A
1.8     20  2   A
1.92    11  19  B
2.04    8   13  B
2.16    5   8   B
2.28    14  18  B
2.40    7   2   B
2.52    12  5   C
2.64    4   11  C
2.76    1   13  C
2.88    16  9   C
3       14  17  C

我想看起来像这样: shaded time-series example

2 个答案:

答案 0 :(得分:0)

您需要保存每个颜色区域的开头和结尾,然后使用matplotlib.axvspan为这些区域着色。例如,这里假设以下数据框:

import matplotlib.pyplot as plt
import numpy as np
df = {'time': [0.00,0.12,0.24,0.36, 0.48],
  'A':[10,4,14,5,8],
  'B':[2,20,16,16,13],
  'C':['A','A','B','C','A']}
A = []
B = []
C = []
for i in range(1,len(df)+1):
    if i== len(df)+1:
        df['time'][i] = 0.48
    elif df['C'][i] == 'A':
        A.append([df['time'][i-1], df['time'][i]])
    elif df['C'][i] == 'B':
        B.append([df['time'][i-1], df['time'][i]])
    else:
        C.append([df['time'][i-1], df['time'][i]])

现在每个区域的开始和结束都保存在每个数组(A,B,C)中,您可以使用

绘制这些区域
plt.plot(df['time'], df['A'])
plt.plot(df['time'], df['B'])
for i in A:
    plt.axvspan(i[0],i[1], facecolor='orange', alpha=0.5)
for i in B:
    plt.axvspan(i[0],i[1], facecolor='crimson', alpha=0.5)
for i in C:
    plt.axvspan(i[0],i[1], facecolor='lavender', alpha=0.5)
plt.show()
plt.savefig('x.png')

time_series

答案 1 :(得分:0)

这是我的尝试。该代码用于给定的数据,可能对其他数据有效或无效。

data = """
time,seriesA,seriesB,Condition
0.00 ,   10 , 2  ,A
0.12 ,   4  , 20 ,A
0.24 ,   14 , 16 ,A
0.36 ,   5  , 16 ,A
0.48 ,   8  , 13 ,A
0.6  ,   5  , 16 ,B
0.72 ,   17 , 3  ,B
0.84 ,   8  , 20 ,B
0.96 ,   3  , 3  ,B
1.08 ,   18 , 20 ,C
1.20 ,   11 , 13 ,C
1.32 ,   8  , 10 ,C
1.44 ,   17 , 11 ,A
1.56 ,   15 , 2  ,A
1.68 ,   1  , 1  ,A
1.8  ,   20 , 2  ,A
1.92 ,   11 , 19 ,B
2.04 ,   8  , 13 ,B
2.16 ,   5  , 8  ,B
2.28 ,   14 , 18 ,B
2.40 ,   7  , 2  ,B
2.52 ,   12 , 5  ,C
2.64 ,   4  , 11 ,C
2.76 ,   1  , 13 ,C
2.88 ,   16 , 9  ,C
3    ,   14 , 17 ,C
"""
with open("time_series_with_axspan.txt", "wt") as f:
    f.write(data)

d = pd.read_csv("time_series_with_axspan.txt")

d.plot(x='time', y=['seriesA', 'seriesB'])

ax = plt.gca()

# create spans; is there an easier way of doing this in pandas?
condition = d['Condition']
current_c = condition[0]
spans = [[0, 0]]
for i, c in enumerate(condition):
    if c != current_c:
        # change to i-1 if gap between two conditions is to be left empty
        spans[-1][-1] = i
        spans.append([i, None])
        current_c = c
# assumes that the last condition is not on its own but same as previous
spans[-1][-1] = len(condition)-1

# The following works since are three unique conditions appearing one after 
# the other. Any three colors will work for example 
# color=cycle(['r', 'g', 'b'])
from itertools import cycle
colors = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'][-3:])
for span in spans:
    ax.axvspan(d.iloc[span[0], 0], d.iloc[span[1], 0], color=next(colors))

time series with spans

希望这会有所帮助。