叠加折线图和面积图:将衰退条添加到时间序列

数据挖掘 时间序列
2022-02-24 03:12:25

我正在尝试从 FRED 重建时间序列图:https ://fred.stlouisfed.org/series/LABSHPUSA156NRUG使用 Python。但是,我无法得到一个清晰的数字,其中时间序列与代表衰退条的面积图重叠。

我对 python 还是很陌生,所以找到一个简单的原因为什么我的尝试不起作用是令人沮丧的。

我尝试过这两种方法。

我的第一次尝试如下所示:

fig, ax = plt.subplots()
ls_data.plot.line(ax=ax, figsize=(8,5), x='Date', color=blue)
rec_data.plot.area(ax=ax, figsize=(8,5), x='Date', alpha=0.5, color=gray)
plt.ylim(0.59,0.65)

并产生以下令人困惑的混乱:在此处输入图像描述

我的第二次尝试是“ax2 = ax1.twinx()”路线

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ls_data.plot.line(figsize=(8,5), x='Date', color=blue)
rec_data.plot.area(figsize=(8,5), x='Date', alpha=0.5, color=gray)

但是,这会产生两个单独的数字。

在此处输入图像描述

在此处输入图像描述

一个可能的问题是,劳动份额的 x 值是按个别年份绘制的,而衰退的 x 值是按月绘制的。但根据第二次尝试,看起来图表应该平滑叠加,但我很可能会得到与第一次尝试相同的结果。转变衰退数据能否解决问题?

编辑:经济衰退日期的数据可在此处获得。https://fred.stlouisfed.org/series/USREC#:~:text=For%20daily%20data%2C%20the%20recession,the%20month%20of%20the%20trough

2个回答

将 FRED 的数据用于劳动力数据衰退数据,并对您的代码进行轻微调整,我想我会得到您想要的结果:

import pandas as pd
import matplotlib.pyplot as plt

# read in data
rec_data = pd.read_csv("USREC.csv")
ls_data = pd.read_csv("LABSHPUSA156NRUG.csv")

# make sure date columns are actual dates
rec_data["DATE"] = pd.to_datetime(rec_data["DATE"])
ls_data["DATE"] = pd.to_datetime(ls_data["DATE"])

# create plot
fig, ax = plt.subplots()
ls_data.plot.line(ax=ax, figsize=(8, 5), x='DATE', color="blue")
rec_data.plot.area(ax=ax, figsize=(8, 5), x='DATE', alpha=0.5, color="gray")
plt.xlim("1950-01-01", "2020-01-01")
plt.ylim(0.58, 0.65)

在此处输入图像描述

Oxbowerce 的回答似乎有问题,所以我想提供一个替代方案。衰退数据是月度数据,而劳动力市场数据是年度数据:为了解决这种差异,我将年度数据重新采样为月度数据,使用简单平均值进行插值,合并数据并绘制图。随着数据在同一日期合并,奇怪的视觉伪影消失了。

1.问题

要查看 Oxbowerce 方法的问题,让我们为较小的数据样本创建一个图。使用 Oxbowerce 的代码但放大 2007-2009:

衰退线不是垂直的!

在此处输入图像描述

2.一种解决方案

可能有一种pandas解决方法可以无缝地绘制不同频率的数据,而不会出现上述奇怪的伪影,但我不知道,所以我花了很长的时间重新采样数据。

2a:使用前向填充“.ffill()”重新采样到每月

dy = df.set_index('DATE').resample('M').ffill().reset_index()
d1 = pd.merge(dr, dy, left_index=True, right_index=True, suffixes=("", "_y")).drop(labels='DATE_y', axis=1)

中间产品:

在此处输入图像描述

现在劳动力市场数据看起来参差不齐。所以我们插值。

2b:使用 '.mean().interpolate('linear')' 重新采样到每月

# interpolate data | MS='Month Start', default is M=ME='Month End'
di = df.set_index('DATE').resample('1MS').mean().interpolate('linear').reset_index()
d2 = pd.merge(dr, di, left_index=True, right_index=True, suffixes=("", "_y")).drop(labels='DATE_y', axis=1)

完成品:

在此处输入图像描述

绘制衰退区域的代码:

# convenience function
def plot_series(ax, df, index, cols, area, **kwargs):
    # convert area variable to boolean
    df[area] = df[area].astype(int).astype(bool)
    # set up an index based on date
    df = df.set_index(keys=index, drop=False)
    # line plot
    df.plot(ax=ax, x=index, y=cols, **kwargs)
    # extract limits
    y1, y2 = ax.get_ylim()
    ax.fill_between(df[index].index, y1=y1, y2=y2, where=df[area], facecolor='grey', alpha=0.4)
    return ax

# plot resampled data with method='ffill'
f, ax = plt.subplots()
plot_series(ax, d1, index='DATE', cols='LABSHPUSA156NRUG', area='USREC')
ax.grid(True)
plt.show()

# plot resampled data with .mean().interpolate('linear')
f, ax = plt.subplots()
plot_series(ax, d2, index='DATE', cols='LABSHPUSA156NRUG', area='USREC')
ax.grid(True)
plt.show()