code: def create_schema_graph(
      tables=None,
      metadata=None,
      show_indexes=True,
      show_datatypes=True,
      font="Bitstream-Vera Sans",
      concentrate=True,
      relation_options={},
      rankdir="TB",
      show_column_keys=False,
      restrict_tables=None,
      show_schema_name=False,
      format_schema_name=None,
      format_table_name=None,
  ):
      """
      Args:
        - metadata (sqlalchemy.MetaData, default=None): SqlAlchemy `MetaData` with reference to related tables.  If none
          is provided, uses metadata from first entry of `tables` argument.
        - concentrate (bool, default=True): Specifies if multiedges should be merged into a single edge & partially
          parallel edges to share overlapping path.  Passed to `pydot.Dot` object.
        - relation_options (dict, default: None): kwargs passed to pydot.Edge init.  Most attributes in
          pydot.EDGE_ATTRIBUTES are viable options.  A few values are set programmatically.
        - rankdir (string, default='TB'): Sets direction of graph layout.  Passed to `pydot.Dot` object.  Options are
          'TB' (top to bottom), 'BT' (bottom to top), 'LR' (left to right), 'RL' (right to left).
        - show_column_keys (bool, default=False): If true then add a PK/FK suffix to columns names that are primary and
          foreign keys.
        - restrict_tables (None or list of strings): Restrict the graph to only consider tables whose name are defined
          `restrict_tables`.
        - show_schema_name (bool, default=False): If true, then prepend '<schema name>.' to the table name resulting in
          '<schema name>.<table name>'.
        - format_schema_name (dict, default=None): If provided, allowed keys include: 'color' (hex color code incl #),
          'fontsize' as a float, and 'bold' and 'italics' as bools.
        - format_table_name (dict, default=None): If provided, allowed keys include: 'color' (hex color code incl #),
          'fontsize' as a float, and 'bold' and 'italics' as bools.
      """
  
      relation_kwargs = {"fontsize": "7.0", "dir": "both"}
      relation_kwargs.update(relation_options)
  
      if metadata is None and tables is not None and len(tables):
          metadata = tables[0].metadata
      elif tables is None and metadata is not None:
          if not len(metadata.tables):
              metadata.reflect()
          tables = metadata.tables.values()
      else:
          raise ValueError(
              "You need to specify at least tables or metadata"
          )
  
      # check if unexpected keys were used in format_schema_name param
      if (
          format_schema_name is not None
          and len(
              set(format_schema_name.keys()).difference(
                  {"color", "fontsize", "italics", "bold"}
              )
          )
          > 0
      ):
          raise KeyError(
              "Unrecognized keys were used in dict provided for `format_schema_name` parameter"
          )
      # check if unexpected keys were used in format_table_name param
      if (
          format_table_name is not None
          and len(
              set(format_table_name.keys()).difference(
                  {"color", "fontsize", "italics", "bold"}
              )
          )
          > 0
      ):
          raise KeyError(
              "Unrecognized keys were used in dict provided for `format_table_name` parameter"
          )
  
      graph = pydot.Dot(
          prog="dot",
          mode="ipsep",
          overlap="ipsep",
          sep="0.01",
          concentrate=str(concentrate),
          rankdir=rankdir,
      )
      if restrict_tables is None:
          restrict_tables = set([t.name.lower() for t in tables])
      else:
          restrict_tables = set([t.lower() for t in restrict_tables])
      tables = [t for t in tables if t.name.lower() in restrict_tables]
      for table in tables:
          graph.add_node(
              pydot.Node(
                  str(table.name),
                  shape="plaintext",
                  label=_render_table_html(
                      table,
                      metadata,
                      show_indexes,
                      show_datatypes,
                      show_column_keys,
                      show_schema_name,
                      format_schema_name,
                      format_table_name,
                  ),
                  fontname=font,
                  fontsize="7.0",
              )
          )
  
      for table in tables:
          for fk in table.foreign_keys:
              if fk.column.table not in tables:
                  continue
              edge = [table.name, fk.column.table.name]
              is_inheritance = (
                  fk.parent.primary_key and fk.column.primary_key
              )
              if is_inheritance:
                  edge = edge[::-1]
              graph_edge = pydot.Edge(
                  headlabel="+ %s" % fk.column.name,
                  taillabel="+ %s" % fk.parent.name,
                  arrowhead=is_inheritance and "none" or "odot",
                  arrowtail=(fk.parent.primary_key or fk.parent.unique)
                  and "empty"
                  or "crow",
                  fontname=font,
                  # samehead=fk.column.name, sametail=fk.parent.name,
                  *edge,
                  **relation_kwargs,
              )
              graph.add_edge(graph_edge)
  
      # not sure what this part is for, doesn't work with pydot 1.0.2
      #            graph_edge.parent_graph = graph.parent_graph
      #            if table.name not in [e.get_source() for e in graph.get_edge_list()]:
      #                graph.edge_src_list.append(table.name)
      #            if fk.column.table.name not in graph.edge_dst_list:
      #                graph.edge_dst_list.append(fk.column.table.name)
      #            graph.sorted_graph_elements.append(graph_edge)
      return graph
  
file_path: evadb/script/docs/catalog_plotter.py
imports: from evadb.catalog.catalog_manager import CatalogManager
  from evadb.configuration.configuration_manager import ConfigurationManager
  from sqlalchemy.orm.properties import RelationshipProperty
  import pydot
  import types
  from sqlalchemy.dialects.postgresql.base import PGDialect
  from sqlalchemy import MetaData, Table, text, ForeignKeyConstraint
label_desc: Use image node_id 5 for calling a global function with example usage: create_schema_graph(tables, metadata, show_indexes, show_datatypes, font, concentrate, relation_options, rankdir, show_column_keys, restrict_tables, show_schema_name, format_schema_name, format_table_name) and returns: graph