docstr: Plot actuals vs prediction and attention
  
  Args:
      x (Dict[str, torch.Tensor]): network input
      out (Dict[str, torch.Tensor]): network output
      idx (int): sample index
      plot_attention: if to plot attention on secondary axis
      add_loss_to_title: if to add loss to title. Default to False.
      show_future_observed: if to show actuals for future. Defaults to True.
      ax: matplotlib axes to plot on
  
  Returns:
      plt.Figure: matplotlib figure
docstr_tok: ["Plot","actuals","vs","prediction","and","attention","Args",":","x","(","Dict","[","str",",","torch.Tensor","]",")",":","network","input","out","(","Dict","[","str",",","torch.Tensor","]",")",":","network","output","idx","(","int",")",":","sample","index","plot_attention",":","if","to","plot","attention","on","secondary","axis","add_loss_to_title",":","if","to","add","loss","to","title",".","Default","to","False",".","show_future_observed",":","if","to","show","actuals","for","future",".","Defaults","to","True",".","ax",":","matplotlib","axes","to","plot","on","Returns",":","plt.Figure",":","matplotlib","figure"]
code: def plot_prediction(
      self,
      x: Dict[str, torch.Tensor],
      out: Dict[str, torch.Tensor],
      idx: int,
      plot_attention: bool = True,
      add_loss_to_title: bool = False,
      show_future_observed: bool = True,
      ax=None,
      **kwargs,
  ) -> plt.Figure:
      """
      Plot actuals vs prediction and attention
  
      Args:
          x (Dict[str, torch.Tensor]): network input
          out (Dict[str, torch.Tensor]): network output
          idx (int): sample index
          plot_attention: if to plot attention on secondary axis
          add_loss_to_title: if to add loss to title. Default to False.
          show_future_observed: if to show actuals for future. Defaults to True.
          ax: matplotlib axes to plot on
  
      Returns:
          plt.Figure: matplotlib figure
      """
  
      # plot prediction as normal
      fig = super().plot_prediction(
          x,
          out,
          idx=idx,
          add_loss_to_title=add_loss_to_title,
          show_future_observed=show_future_observed,
          ax=ax,
          **kwargs,
      )
  
      # add attention on secondary axis
      if plot_attention:
          interpretation = self.interpret_output(
              out.iget(slice(idx, idx + 1))
          )
          for f in to_list(fig):
              ax = f.axes[0]
              ax2 = ax.twinx()
              ax2.set_ylabel("Attention")
              encoder_length = x["encoder_lengths"][0]
              ax2.plot(
                  torch.arange(-encoder_length, 0),
                  interpretation["attention"][0, -encoder_length:]
                  .detach()
                  .cpu(),
                  alpha=0.2,
                  color="k",
              )
              f.tight_layout()
      return fig
  
imports: from copy import copy
  from typing import Dict, List, Tuple, Union
  from matplotlib import pyplot
  import numpy
  import torch
  from torch import nn
  from torchmetrics import Metric
  from pytorch_forecasting.data import TimeSeriesDataSet
  from pytorch_forecasting.data.encoders import NaNLabelEncoder
  from pytorch_forecasting.metrics import MAE, MAPE, MASE, RMSE, SMAPE, MultiHorizonMetric, MultiLoss, QuantileLoss
  from pytorch_forecasting.models.base_model import BaseModelWithCovariates
  from pytorch_forecasting.models.nn import LSTM, MultiEmbedding
  from pytorch_forecasting.models.temporal_fusion_transformer.sub_modules import AddNorm, GateAddNorm, GatedLinearUnit, GatedResidualNetwork, InterpretableMultiHeadAttention, VariableSelectionNetwork
  from pytorch_forecasting.utils import create_mask, detach, integer_histogram, masked_op, padded_stack, to_list
label_desc: Use image node_id 11 for calling the TemporalFusionTransformer obj's underlying member method code with example usage: obj.plot_prediction(x, out, idx, plot_attention, add_loss_to_title, show_future_observed, ax) and returns: fig