code: def astviz_dot(
      statement: str,
      frame="current",
      dtype_colors=None,
      dtype_precisions=None,
      dtype_alpha_range=None,
  ) -> str:
      def internal_label(node):
          sh = tsensor.analysis._shape(node.value)
          ty = tsensor.analysis._dtype(node.value)
          text = "".join(str(t) for t in node.optokens)
          if sh is None:
              return f'<font face="{fontname}" point-size="{fontsize}">{text}</font>'
  
          sz = "x".join(
              [PyVizView.nabbrev(sh[i]) for i in range(len(sh))]
          )
          return f"""<font face="Consolas" color="#444443" point-size="{fontsize}">{text}</font><br/><font face="Arial" color="#444443" point-size="{dimfontsize}">{sz}</font><br/><font face="Arial" color="#444443" point-size="{dimfontsize}">&lt;{ty}&gt;</font>"""
  
      dtype_color_info = DTypeColorInfo(
          dtype_colors, dtype_precisions, dtype_alpha_range
      )
  
      root, tokens = tsensor.parsing.parse(statement)
  
      if frame == "current":  # use frame of caller if nothing passed in
          frame = sys._getframe().f_back
          if frame.f_code.co_name == "astviz":
              frame = frame.f_back
  
      if (
          frame is not None
      ):  # if the passed in None, then don't do the evaluation
          root.eval(frame)
  
      nodes = tsensor.ast.postorder(root)
      atoms = tsensor.ast.leaves(root)
      atomsS = set(atoms)
      ops = [nd for nd in nodes if nd not in atomsS]  # keep order
  
      gr = """digraph G {
          margin=0;
          nodesep=.01;
          ranksep=.3;
          rankdir=BT;
          ordering=out; # keep order of leaves
      """
  
      fontname = "Consolas"
      fontsize = 12
      dimfontsize = 9
      spread = 0
  
      # Gen leaf nodes
      for i in range(len(tokens)):
          t = tokens[i]
          if t.type != token.ENDMARKER:
              nodetext = t.value
              # if ']' in nodetext:
              if nodetext == "]":
                  nodetext = nodetext.replace(
                      "]", "&zwnj;]"
                  )  # &zwnj; is 0-width nonjoiner. ']' by itself is bad for DOT
              label = f'<font face="{fontname}" color="#444443" point-size="{fontsize}">{nodetext}</font>'
              _spread = spread
              if t.type == token.DOT:
                  _spread = 0.1
              elif t.type == token.EQUAL:
                  _spread = 0.25
              elif t.type in tsensor.parsing.ADDOP:
                  _spread = 0.4
              elif t.type in tsensor.parsing.MULOP:
                  _spread = 0.2
              gr += f"leaf{id(t)} [shape=box penwidth=0 margin=.001 width={_spread} label=<{label}>]\n"
  
      # Make sure leaves are on same level
      gr += f"{{ rank=same; "
      for t in tokens:
          if t.type != token.ENDMARKER:
              gr += f" leaf{id(t)}"
      gr += "\n}\n"
  
      # Make sure leaves are left to right by linking
      for i in range(len(tokens) - 2):
          t = tokens[i]
          t2 = tokens[i + 1]
          gr += f"leaf{id(t)} -> leaf{id(t2)} [style=invis];\n"
  
      # Draw internal ops nodes
      for nd in ops:
          label = internal_label(nd)
          sh = tsensor.analysis._shape(nd.value)
          if sh is None:
              color = ""
          else:
              ty = tsensor.analysis._dtype(nd.value)
              color = dtype_color_info.color(ty)
              color = mc.rgb2hex(color, keep_alpha=True)
              color = f'fillcolor="{color}" style=filled'
          gr += f"node{id(nd)} [shape=box {color} penwidth=0 margin=0 width=.25 height=.2 label=<{label}>]\n"
  
      # Link internal nodes to other nodes or leaves
      for nd in nodes:
          kids = nd.kids
          for sub in kids:
              if sub in atomsS:
                  gr += f'node{id(nd)} -> leaf{id(sub.token)} [dir=back, penwidth="0.5", color="#6B6B6B", arrowsize=.3];\n'
              else:
                  gr += f'node{id(nd)} -> node{id(sub)} [dir=back, penwidth="0.5", color="#6B6B6B", arrowsize=.3];\n'
  
      gr += "}\n"
      return gr
  
imports: import sys
  import os
  from pathlib import Path
  import tempfile
  import graphviz
  import graphviz.backend
  import token
  import matplotlib.patches
  import matplotlib.pyplot
  import matplotlib.colors
  from IPython.display import display, SVG
  from IPython import get_ipython
  import numpy
  import tsensor
  import tsensor.ast
  import tsensor.analysis
  import tsensor.parsing
label_desc: Use image node_id 3 for calling a global function with example usage: astviz_dot(statement, frame, dtype_colors, dtype_precisions, dtype_alpha_range) and returns: gr, str, fontsize, str, text, str, dimfontsize, str, sz, str, dimfontsize, str, ty, str, str, fontname, str, fontsize, str, text, str