class_docstr: Conducts NMF and holds the models and components 
class_docstr_tok: ["Conducts","NMF","and","holds","the","models","and","components"]
docstr: Show interactive explorable for a single sequence with sparklines to isolate factors.
  
  Example:
      ![NMF Example](../../img/nmf_ex_1.png)
  Args:
      input_sequence: Which sequence in the batch to show.
docstr_tok: ["Show","interactive","explorable","for","a","single","sequence","with","sparklines","to","isolate","factors",".","Example",":","!","[","NMF","Example","]","(","..","\/","..","\/img\/nmf_ex_1.png",")","Args",":","input_sequence",":","Which","sequence","in","the","batch","to","show","."]
code: def explore(self, input_sequence: int = 0, **kwargs):
      """
      Show interactive explorable for a single sequence with sparklines to isolate factors.
  
      Example:
          ![NMF Example](../../img/nmf_ex_1.png)
      Args:
          input_sequence: Which sequence in the batch to show.
      """
      tokens = []
  
      for idx, token in enumerate(
          self.tokens[input_sequence]
      ):  # self.tokens[:-1]
          type = "input" if idx < self.n_input_tokens else "output"
          tokens.append(
              {
                  "token": token,
                  "token_id": int(self.token_ids[input_sequence][idx]),
                  # 'token_id': int(self.token_ids[idx]),
                  "type": type,
                  # 'value': str(components[0][comp_num][idx]),  # because json complains of floats
                  "position": idx,
              }
          )
  
      # If the sequence contains both input and generated tokens:
      # Duplicate the factor at index 'n_input_tokens'. THis way
      # each token has an activation value (instead of having one activation less than tokens)
      # But with different meanings: For inputs, the activation is a response
      # For outputs, the activation is a cause
      if len(self.token_ids[input_sequence]) != self.n_input_tokens:
          # Case: Generation. Duplicate value of last input token.
          factors = np.array(
              [
                  np.concatenate(
                      [
                          comp[: self.n_input_tokens],
                          comp[self.n_input_tokens - 1 :],
                      ]
                  )
                  for comp in self.components
              ]
          )
          factors = [
              comp.tolist() for comp in factors
          ]  # the json conversion needs this
      else:
          # Case: no generation
          factors = [
              comp.tolist() for comp in self.components
          ]  # the json conversion needs this
  
      data = {
          # A list of dicts. Each in the shape {
          # Example: [{'token': 'by', 'token_id': 2011, 'type': 'input', 'position': 235}]
          "tokens": tokens,
          # Three-dimensional list. Shape: (1, factors, sequence length)
          "factors": [factors],
      }
      d.display(
          d.HTML(
              filename=os.path.join(self._path, "html", "setup.html")
          )
      )
  
      js = f"""
           requirejs(['basic', 'ecco'], function(basic, ecco){{
              const viz_id = basic.init()
              
              ecco.interactiveTokensAndFactorSparklines(viz_id, {data},
              {{
              'hltrCFG': {{'tokenization_config': {json.dumps(self.config['tokenizer_config'])}
                  }}
              }})
           }}, function (err) {{
              console.log(err);
          }})"""
      d.display(d.Javascript(js))
  
      if "printJson" in kwargs and kwargs["printJson"]:
          print(data)
          return data
  
imports: import os
  import json
  import ecco
  from IPython import display
  from ecco import util, lm_plots
  import random
  import matplotlib.pyplot
  import numpy
  import torch
  from torch.nn import functional
  from sklearn import decomposition
  from typing import Dict, Optional, List, Tuple, Union
  from ecco.util import strip_tokenizer_prefix, is_partial_token
label_desc: Use image node_id 3 for calling the NMF obj's underlying member method code with example usage: obj.explore(input_sequence) and returns: data