根据事件的发生向 Seaborn Facet Grid 图添加垂直线
Add vertical lines to Seaborn Facet Grid plots based on the occurrence of an event
我有 60 个月内 50 个不同个体的面板数据。我已经使用 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
- 'f_a'是ID(分组变量)
- 'tone'是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')
这是绘图输出的示例:
Plots
这是我用来生成数据的代码:
# 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='--')
我有 60 个月内 50 个不同个体的面板数据。我已经使用 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
- 'f_a'是ID(分组变量)
- 'tone'是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')
这是绘图输出的示例: Plots
这是我用来生成数据的代码:
# 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='--')