code: def plot_clustered_activations(
      tokens,
      activations,
      clusters,
      cluster_ids,
      file_prefix="neuron_activation_plot",
  ):
      """Plots a heat mapshowing how active each neuron (row) was with each token
      (columns). Neurons with activation less then masking_threashold are masked.
  
      Args:
        tokens: list of the tokens. Note if you're examining activations
        associated with the token as input or as output.
  
  
      """
      n_tokens = activations.shape[-1]
      # Activations lower than this threshold will show up as blank
      masking_threshold = 0.01
      masked = np.ma.masked_less(activations, masking_threshold)
      # mask = tensor.shape()
  
      fig = plt.figure(
          figsize=(activations.shape[1], 60)
      )  # Width adjusts to number of tokens
  
      # sns.set()
      ax = plt.gca()
  
      v = copy.copy(get_cmap("viridis_r"))
      v.set_bad("white")
      g = sns.heatmap(
          activations,
          mask=masked.mask,
          cmap=v,
          ax=ax,
          vmax=2,
          vmin=0,
          cbar=False,
      )
  
      colors = get_cmap("cool", len(clusters.keys()))
      colors = get_cmap("tab20", len(clusters.keys()))
      colors_2 = get_cmap("hot", len(clusters.keys()))
      colors_2 = get_cmap("prism", len(clusters.keys()))
  
      row = 0
      for idx, (cluster_id, neurons) in enumerate(clusters.items()):
          n_neurons = len(neurons)
          # print(idx, 'cluster #', cluster_id, "number of neurons: ",
          #       len(neurons), n_neurons, 'row', row)
  
          opacity = 0.00
  
          edge_color = colors(idx, 0.5)
          fill_color = edge_color  # colors(idx, opacity)
  
          # if idx % 2 == 0:
          #     edge_color = colors(idx)
          #     fill_color = colors(idx, opacity)  # Color + Opacity
          # else:
          #     edge_color = colors_2(idx)
          #     fill_color = colors_2(idx, opacity)  # Color + Opacity
  
          # First colored column to the leftmost of the figure identifying the cluster
          g.add_patch(
              Rectangle(
                  (-1, row),
                  1,  # width
                  n_neurons,  # height
                  fill=True,
                  facecolor=edge_color,
                  edgecolor=edge_color,
                  lw=5,
                  label="cluster {}".format(cluster_ids[idx]),
              )
          )
  
          # Border surrounding the cluster
          g.add_patch(
              Rectangle(
                  (-1, row),
                  activations.shape[1] + 1,  # width - span all columns
                  n_neurons,  # height
                  fill=False,
                  facecolor=fill_color,
                  edgecolor=edge_color,
                  lw=5,
              )
          )
          row += n_neurons
  
      # ax_ = g.ax_heatmap
      # print(ax_)
  
      # From https://github.com/mwaskom/seaborn/issues/1773
      # fix for mpl bug that cuts off top/bottom of seaborn viz
      left, right = plt.xlim()  # discover the values for bottom and top
      # right += 0.5  # Add 0.5 to the bottom
      left -= 0.5  # Subtract 0.5 from the top
      plt.xlim(left, right)  # update the ylim(bottom, top) values
  
      # print(ax_)
  
      if tokens:
          ax.set_xticklabels(tokens[-n_tokens:], rotation=0)
      ax.tick_params(axis="x", which="major", labelsize=28)
  
      plt.tick_params(
          axis="x",  # changes apply to the x-axis
          which="both",  # both major and minor ticks are affected
          left=False,  # ticks along the bottom edge are off
          bottom=True,  # ticks along the bottom edge are off
          top=True,  # ticks along thx top edge are off
          labeltop=True,
          labelbottom=True,
      )  # labels along the bottom edge are off
  
      plt.xticks(rotation=-45)
  
      # # Save Figure to file & download
      fig.set_facecolor("w")
  
      plt.legend(loc="lower left", bbox_to_anchor=(1.05, 0))
      plt.show()
  
file_path: ecco/src/ecco/lm_plots.py
imports: import seaborn
  import matplotlib.pyplot
  import numpy
  from matplotlib.patches import Rectangle
  from matplotlib.cm import get_cmap
  import copy
  import warnings
  from matplotlib.colors import ListedColormap
  import matplotlib
  from matplotlib.ticker import FuncFormatter
  from typing import Optional, List, Dict
  import sys
label_desc: Use image node_id 2 for calling a global function with example usage: plot_clustered_activations(tokens, activations, clusters, cluster_ids, file_prefix) without return types