Python 根据事件的发生向Seaborn镶嵌面栅格图添加垂直线

Python 根据事件的发生向Seaborn镶嵌面栅格图添加垂直线,python,python-3.x,matplotlib,seaborn,lattice,Python,Python 3.x,Matplotlib,Seaborn,Lattice,我有50个不同个体60个月的小组数据。我已经使用Seaborn创建了刻面网格来绘制每个个体随时间变化的色调,现在我想添加事件发生时的垂直线。理想情况下,我想在事件1发生时添加一条蓝线,在事件2发生时添加一条红线 数据样本: f_a tone t event1 event2 01_01 -1.9 0 0 0 01_01 -1.1 1 1 0 01_01 -2.5 2 0

我有50个不同个体60个月的小组数据。我已经使用Seaborn创建了刻面网格来绘制每个个体随时间变化的色调,现在我想添加事件发生时的垂直线。理想情况下,我想在事件1发生时添加一条蓝线,在事件2发生时添加一条红线

数据样本:

f_a    tone    t     event1    event2
01_01  -1.9    0       0         0
01_01  -1.1    1       1         0
01_01  -2.5    2       0         0
01_01  -3.0    3       0         1
...
01_01   1.3    40      1         0
01_01   0.7    41      0         0
01_01  -0.6    42      0         0
01_01  -2.3    43      0         1
# Create list of observation pairs
fs = np.arange(1,11,1)
ans = np.arange(1,6,1)
f_a=[str(f).zfill(2)+'_'+str(a).zfill(2) 
     for f in fs for a in ans]
# Create dataframe with ARMA process by f_a pair with 60 months of observations of tone
# per pair
d={}
for f in f_a:
    arparams = np.array([.5, .25])
    maparams = np.array([.5, .3])
    ar = np.r_[1,-arparams]
    ma = np.r_[1, maparams]
    y = sm.tsa.arma_generate_sample(ar,ma,60)
    d[f]=y
    
df=pd.melt(pd.DataFrame(d)).rename(columns={'variable':'f_a','value':'tone'})
df['t']=df.groupby('f_a').cumcount()

# One occurrence of event 1 and 2 per f_a pair
up = [np.random.choice(np.arange(2,61,1)) for f in f_a]
down = [np.random.choice(np.arange(2,61,1)) for f in f_a]

# Dataframe with event 1 and 2
events=pd.DataFrame(data=[f_a,up,down]).T.rename(columns={0:'f_a',1:'event1_t',2:'event2_t'})

# Merge Datasets
df=df.merge(right=events,how='left',on='f_a')

# Create dummies for event1/event2
df['event1']=(df.t==df.event1_t)*1
df['event2']=(df.t==df.event2_t)*1

# Clean up dataset
df=df.drop(columns=['event1_t','event2_t'])
  • “f_a”是ID(分组变量)
  • “音调”是y轴
  • “t”是时间变量
  • 如果事件发生在时间段t内,“event1”和“event2”等于1,否则等于零
  • 以下是我必须创建绘图的代码:

    # Initialize a grid of plots with an Axes for each pair
    grid1 = sns.FacetGrid(df,col='f_a',hue='f_a',col_wrap=5,height=1.5)
    
    #Draw a horizontal line to show the starting point
    grid1.map(plt.axhline,y=0,ls=":",c=".5")
    
    #Draw a line plot to show the trajectory of tone for each f-a pair over time
    grid1.map(plt.plot,"t","tone",marker='o')
    
    以下是绘图输出的示例:

    以下是我用来生成数据的代码:

    f_a    tone    t     event1    event2
    01_01  -1.9    0       0         0
    01_01  -1.1    1       1         0
    01_01  -2.5    2       0         0
    01_01  -3.0    3       0         1
    ...
    01_01   1.3    40      1         0
    01_01   0.7    41      0         0
    01_01  -0.6    42      0         0
    01_01  -2.3    43      0         1
    
    # Create list of observation pairs
    fs = np.arange(1,11,1)
    ans = np.arange(1,6,1)
    f_a=[str(f).zfill(2)+'_'+str(a).zfill(2) 
         for f in fs for a in ans]
    # Create dataframe with ARMA process by f_a pair with 60 months of observations of tone
    # per pair
    d={}
    for f in f_a:
        arparams = np.array([.5, .25])
        maparams = np.array([.5, .3])
        ar = np.r_[1,-arparams]
        ma = np.r_[1, maparams]
        y = sm.tsa.arma_generate_sample(ar,ma,60)
        d[f]=y
        
    df=pd.melt(pd.DataFrame(d)).rename(columns={'variable':'f_a','value':'tone'})
    df['t']=df.groupby('f_a').cumcount()
    
    # One occurrence of event 1 and 2 per f_a pair
    up = [np.random.choice(np.arange(2,61,1)) for f in f_a]
    down = [np.random.choice(np.arange(2,61,1)) for f in f_a]
    
    # Dataframe with event 1 and 2
    events=pd.DataFrame(data=[f_a,up,down]).T.rename(columns={0:'f_a',1:'event1_t',2:'event2_t'})
    
    # Merge Datasets
    df=df.merge(right=events,how='left',on='f_a')
    
    # Create dummies for event1/event2
    df['event1']=(df.t==df.event1_t)*1
    df['event2']=(df.t==df.event2_t)*1
    
    # Clean up dataset
    df=df.drop(columns=['event1_t','event2_t'])
    

    您可以使用
    axvline
    在组上迭代并绘制线。要在子地块上迭代,请使用
    grid1.axes

    for ax, (_, subdata) in zip(grid1.axes, df.groupby('f_a')):
        xs = subdata[subdata['event1'] == 1].t
        for x in xs:
            ax.axvline(x, color='r', ls='--')
    
        xs = subdata[subdata['event2'] == 1].t
        for x in xs:
            ax.axvline(x, color='b', ls='--')