class_docstr: Data class for the return result of LLMAttribution,
  which includes the necessary properties of the attribution.
  It also provides utilities to help present and plot the result in different forms.
class_docstr_tok: ["Data","class","for","the","return","result","of","LLMAttribution",",","which","includes","the","necessary","properties","of","the","attribution",".","It","also","provides","utilities","to","help","present","and","plot","the","result","in","different","forms","."]
docstr: Generate a matplotlib plot for visualising the attribution
  of the output tokens.
  
  Args:
      show (bool): whether to show the plot directly or return the figure and axis
          Default: False
docstr_tok: ["Generate","a","matplotlib","plot","for","visualising","the","attribution","of","the","output","tokens",".","Args",":","show","(","bool",")",":","whether","to","show","the","plot","directly","or","return","the","figure","and","axis","Default",":","False"]
code: def plot_token_attr(self, show=False):
      """
      Generate a matplotlib plot for visualising the attribution
      of the output tokens.
  
      Args:
          show (bool): whether to show the plot directly or return the figure and axis
              Default: False
      """
  
      token_attr = self.token_attr.cpu()
  
      # maximum absolute attribution value
      # used as the boundary of normalization
      # always keep 0 as the mid point to differentiate pos/neg attr
      max_abs_attr_val = token_attr.abs().max().item()
  
      fig, ax = plt.subplots()
  
      # Plot the heatmap
      data = token_attr.numpy()
  
      fig.set_size_inches(
          max(data.shape[1] * 1.3, 6.4), max(data.shape[0] / 2.5, 4.8)
      )
      im = ax.imshow(
          data,
          vmax=max_abs_attr_val,
          vmin=-max_abs_attr_val,
          cmap="RdYlGn",
          aspect="auto",
      )
  
      # Create colorbar
      cbar = ax.figure.colorbar(im, ax=ax)
      cbar.ax.set_ylabel("Token Attribuiton", rotation=-90, va="bottom")
  
      # Show all ticks and label them with the respective list entries.
      ax.set_xticks(np.arange(data.shape[1]), labels=self.input_tokens)
      ax.set_yticks(np.arange(data.shape[0]), labels=self.output_tokens)
  
      # Let the horizontal axes labeling appear on top.
      ax.tick_params(
          top=True, bottom=False, labeltop=True, labelbottom=False
      )
  
      # Rotate the tick labels and set their alignment.
      plt.setp(
          ax.get_xticklabels(),
          rotation=-30,
          ha="right",
          rotation_mode="anchor",
      )
  
      # Loop over the data and create a `Text` for each "pixel".
      # Change the text's color depending on the data.
      for i in range(data.shape[0]):
          for j in range(data.shape[1]):
              val = data[i, j]
              color = "black" if 0.2 < im.norm(val) < 0.8 else "white"
              im.axes.text(
                  j,
                  i,
                  "%.4f" % val,
                  horizontalalignment="center",
                  verticalalignment="center",
                  color=color,
              )
  
      if show:
          plt.show()
      else:
          return fig, ax
  
imports: from copy import copy
  from typing import Callable, cast, Dict, List, Optional, Union
  import matplotlib.pyplot
  import numpy
  import torch
  from captum.attr._core.feature_ablation import FeatureAblation
  from captum.attr._core.kernel_shap import KernelShap
  from captum.attr._core.layer.layer_integrated_gradients import LayerIntegratedGradients
  from captum.attr._core.lime import Lime
  from captum.attr._core.shapley_value import ShapleyValues, ShapleyValueSampling
  from captum.attr._utils.attribution import Attribution
  from captum.attr._utils.interpretable_input import InterpretableInput, TextTemplateInput, TextTokenInput
  from torch import nn, Tensor
label_desc: Use image node_id 3 for calling the LLMAttributionResult obj's underlying member method code with example usage: obj.plot_token_attr(show) and returns: fig,  ax