docstr: Plot interpretation.
  
  Plot two pannels: prediction and backcast vs actuals and
  decomposition of prediction into different block predictions which capture different frequencies.
  
  Args:
      x (Dict[str, torch.Tensor]): network input
      output (Dict[str, torch.Tensor]): network output
      idx (int): index of sample for which to plot the interpretation.
      ax (List[matplotlib axes], optional): list of two matplotlib axes onto which to plot the interpretation.
          Defaults to None.
  
  Returns:
      plt.Figure: matplotlib figure
docstr_tok: ["Plot","interpretation",".","Plot","two","pannels",":","prediction","and","backcast","vs","actuals","and","decomposition","of","prediction","into","different","block","predictions","which","capture","different","frequencies",".","Args",":","x","(","Dict","[","str",",","torch.Tensor","]",")",":","network","input","output","(","Dict","[","str",",","torch.Tensor","]",")",":","network","output","idx","(","int",")",":","index","of","sample","for","which","to","plot","the","interpretation",".","ax","(","List","[","matplotlib","axes","]",",","optional",")",":","list","of","two","matplotlib","axes","onto","which","to","plot","the","interpretation",".","Defaults","to","None",".","Returns",":","plt.Figure",":","matplotlib","figure"]
code: def plot_interpretation(
      self,
      x: Dict[str, torch.Tensor],
      output: Dict[str, torch.Tensor],
      idx: int,
      ax=None,
  ) -> plt.Figure:
      """
      Plot interpretation.
  
      Plot two pannels: prediction and backcast vs actuals and
      decomposition of prediction into different block predictions which capture different frequencies.
  
      Args:
          x (Dict[str, torch.Tensor]): network input
          output (Dict[str, torch.Tensor]): network output
          idx (int): index of sample for which to plot the interpretation.
          ax (List[matplotlib axes], optional): list of two matplotlib axes onto which to plot the interpretation.
              Defaults to None.
  
      Returns:
          plt.Figure: matplotlib figure
      """
      if not isinstance(self.loss, MultiLoss):  # not multi-target
          prediction = self.to_prediction(
              dict(prediction=output["prediction"][[idx]].detach())
          )[0].cpu()
          block_forecasts = [
              self.to_prediction(
                  dict(prediction=block[[idx]].detach())
              )[0].cpu()
              for block in output["block_forecasts"]
          ]
      elif isinstance(
          output["prediction"], (tuple, list)
      ):  # multi-target
          figs = []
          # predictions and block forecasts need to be converted
          prediction = [
              p[[idx]].detach() for p in output["prediction"]
          ]  # select index
          prediction = self.to_prediction(
              dict(prediction=prediction)
          )  # transform to prediction
          prediction = [
              p[0].cpu() for p in prediction
          ]  # select first and only index
  
          block_forecasts = [
              self.to_prediction(
                  dict(prediction=[b[[idx]].detach() for b in block])
              )
              for block in output["block_forecasts"]
          ]
          block_forecasts = [
              [b[0].cpu() for b in block] for block in block_forecasts
          ]
  
          for i in range(len(self.target_names)):
              if ax is not None:
                  ax_i = ax[i]
              else:
                  ax_i = None
  
              figs.append(
                  self.plot_interpretation(
                      dict(
                          encoder_target=x["encoder_target"][i],
                          decoder_target=x["decoder_target"][i],
                      ),
                      dict(
                          backcast=output["backcast"][i],
                          prediction=prediction[i],
                          block_backcasts=[
                              block[i]
                              for block in output["block_backcasts"]
                          ],
                          block_forecasts=[
                              block[i] for block in block_forecasts
                          ],
                      ),
                      idx=idx,
                      ax=ax_i,
                  )
              )
          return figs
      else:
          prediction = output[
              "prediction"
          ]  # multi target that has already been transformed
          block_forecasts = output["block_forecasts"]
  
      if ax is None:
          fig, ax = plt.subplots(
              2, 1, figsize=(6, 8), sharex=True, sharey=True
          )
      else:
          fig = ax[0].get_figure()
  
      # plot target vs prediction
      # target
      prop_cycle = iter(plt.rcParams["axes.prop_cycle"])
      color = next(prop_cycle)["color"]
      ax[0].plot(
          torch.arange(-self.hparams.context_length, 0),
          x["encoder_target"][idx].detach().cpu(),
          c=color,
      )
      ax[0].plot(
          torch.arange(self.hparams.prediction_length),
          x["decoder_target"][idx].detach().cpu(),
          label="Target",
          c=color,
      )
      # prediction
      color = next(prop_cycle)["color"]
      ax[0].plot(
          torch.arange(-self.hparams.context_length, 0),
          output["backcast"][idx][..., 0].detach().cpu(),
          label="Backcast",
          c=color,
      )
      ax[0].plot(
          torch.arange(self.hparams.prediction_length),
          prediction,
          label="Forecast",
          c=color,
      )
  
      # plot blocks
      for pooling_size, block_backcast, block_forecast in zip(
          self.hparams.pooling_sizes,
          output["block_backcasts"][1:],
          block_forecasts,
      ):
          color = next(prop_cycle)["color"]
          ax[1].plot(
              torch.arange(-self.hparams.context_length, 0),
              block_backcast[idx][..., 0].detach().cpu(),
              c=color,
          )
          ax[1].plot(
              torch.arange(self.hparams.prediction_length),
              block_forecast,
              c=color,
              label=f"Pooling size: {pooling_size}",
          )
      ax[1].set_xlabel("Time")
  
      fig.legend()
      return fig
  
imports: from copy import copy
  from typing import Dict, List, Optional, Tuple, Union
  from matplotlib import pyplot
  import numpy
  import torch
  from torch import nn
  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
  from pytorch_forecasting.models.base_model import BaseModelWithCovariates
  from pytorch_forecasting.models.nhits.sub_modules import NHiTS
  from pytorch_forecasting.models.nn.embeddings import MultiEmbedding
  from pytorch_forecasting.utils import create_mask, detach, to_list
label_desc: Use image node_id 9 for calling the NHiTS obj's underlying member method code with example usage: obj.plot_interpretation(x, output, idx, ax) and returns: fig, figs