Visualization of rolling time series forcast

Hi all, I’d like to create a rolling forecast plot of a multi-step time series model.

So the idea is to have the true values time series plotted (hv.Curve()). When I mouse over on a single point of the time series I’d like to see the predicted_0 …_2 as overlay hv.Curve() to the time series.

My data looks like this:

| Index            | true  | predicted_0 | predicted_1 | predicted_2 |
|------------------|-------|-------------|-------------|-------------|
| 2020-02-06 12:00 |  10.1 |             |             |             |
| 2020-02-06 12:01 | 9.7   |             |             |             |
| 2020-02-06 12:02 | 8.2   |             |             |             |

while true predicted_0 …_2 are the next three timestamps that are predicted. So predicted_1 in row 0 is the prediction for the index in row 1, predicted_2 of row 0 is the prediction at time (index) of row 2 and so on…

My first idea was using a Dynamic Map, but it seems dynamic map is not compatible with datetime axis. :expressionless:

I did something like this

def rolling_forecast(uxtime):
    """# https://github.com/holoviz/panel/issues/673 - datetime axis seems impossible using hvplot but could be using panel"""
    timestamp = datetime.datetime.fromtimestamp(uxtime)
    delta = datetime.timedelta(0,60)
    timestamps = [timestamp, timestamp+delta]
    uxtimes = [time.mktime(timestamp.timetuple()), time.mktime((timestamp+delta).timetuple())]
    predictions = [df.loc[timestamp][0], df.loc[timestamp+delta][1]]
    data = list(zip(timestamps, uxtimes, predictions))
    result = pd.DataFrame(data, columns=["time", "uxtime", "prediction"])
    return hv.Curve(result, "time", "prediction")

and use a Dynamic Map like this

dmap = hv.DynamicMap(rolling_forecast, kdims=['uxtime']).opts(height=500, responsive=True)
dmap.redim.range(uxtime=(time.mktime(datetime.datetime(2020,1,29,0,0).timetuple()),time.mktime(datetime.datetime(2020,1,30,0,0).timetuple())))

However I cannot set the step size of uxtime for my minute resolution. I guess I will try further improvements with Panel…

Could improve using Panel

df = pd.DataFrame(multioutputreg.predict(X_test[1:]), index=X_test[1:].index).reset_index().drop_duplicates(keep="first").set_index("index")
unique_timestamps = df.index.map(lambda x: time.mktime(x.timetuple())).unique().values
slider = pn.widgets.IntSlider(name='Unixtime', start=int(min(unique_timestamps)), end=int(max(unique_timestamps)), step=60)
static = raw["count"].loc["2020-01-25":"2020-02"].hvplot(color="gray")

@pn.depends(slider.param.value)
def rolling_forecast(uxtime):
    """# https://github.com/holoviz/panel/issues/673 - datetime axis seems impossible using hvplot but could be using panel"""
    timestamp = datetime.datetime.fromtimestamp(uxtime)
    delta = datetime.timedelta(0,60)
    timestamps = [timestamp, timestamp+delta]
    uxtimes = [time.mktime(timestamp.timetuple()), time.mktime((timestamp+delta).timetuple())]
    predictions = [df.loc[timestamp][0], df.loc[timestamp+delta][1]]
    data = list(zip(timestamps, uxtimes, predictions))
    result = pd.DataFrame(data, columns=["time", "uxtime", "prediction"])
    return hv.Curve(result, "time", "prediction").opts(width=1200, height=300)

pn.Column(’### Rolling Forecast’, slider, static * rolling_forecast).servable()

However
(a) each time I update the slider, the plot is reset to initial state (after zooming, etc.)
(b) I don’t know how I can do overlay with the static time series unless returning static* hv.Curve in the result, which is a bad because the static plot is recalculated each time, which produces overhead

Any help appreciated! :slight_smile: