docs: def plot(self, workflow=None, view=True, depth=-1, name=NONE, comment=NONE,
               format=NONE, engine=NONE, encoding=NONE, graph_attr=NONE,
               node_attr=NONE, edge_attr=NONE, body=NONE, node_styles=NONE,
               node_data=NONE, node_function=NONE, edge_data=NONE, max_lines=NONE,
               max_width=NONE, directory=None, sites=None, index=False):
          """
          Plots the Dispatcher with a graph in the DOT language with Graphviz.
  
          :param workflow:
             If True the latest solution will be plotted, otherwise the dmap.
          :type workflow: bool, optional
  
          :param view:
              Open the rendered directed graph in the DOT language with the sys
              default opener.
          :type view: bool, optional
  
          :param edge_data:
              Edge attributes to view.
          :type edge_data: tuple[str], optional
  
          :param node_data:
              Data node attributes to view.
          :type node_data: tuple[str], optional
  
          :param node_function:
              Function node attributes to view.
          :type node_function: tuple[str], optional
  
          :param node_styles:
              Default node styles according to graphviz node attributes.
          :type node_styles: dict[str|Token, dict[str, str]]
  
          :param depth:
              Depth of sub-dispatch plots. If negative all levels are plotted.
          :type depth: int, optional
  
          :param name:
              Graph name used in the source code.
          :type name: str
  
          :param comment:
              Comment added to the first line of the source.
          :type comment: str
  
          :param directory:
              (Sub)directory for source saving and rendering.
          :type directory: str, optional
  
          :param format:
              Rendering output format ('pdf', 'png', ...).
          :type format: str, optional
  
          :param engine:
              Layout command used ('dot', 'neato', ...).
          :type engine: str, optional
  
          :param encoding:
              Encoding for saving the source.
          :type encoding: str, optional
  
          :param graph_attr:
              Dict of (attribute, value) pairs for the graph.
          :type graph_attr: dict, optional
  
          :param node_attr:
              Dict of (attribute, value) pairs set for all nodes.
          :type node_attr: dict, optional
  
          :param edge_attr:
              Dict of (attribute, value) pairs set for all edges.
          :type edge_attr: dict, optional
  
          :param body:
              Dict of (attribute, value) pairs to add to the graph body.
          :type body: dict, optional
  
          :param directory:
              Where is the generated Flask app root located?
          :type directory: str, optional
  
          :param sites:
              A set of :class:`~schedula.utils.drw.Site` to maintain alive the
              backend server.
          :type sites: set[~schedula.utils.drw.Site], optional
  
          :param index:
              Add the site index as first page?
          :type index: bool, optional
  
          :param max_lines:
              Maximum number of lines for rendering node attributes.
          :type max_lines: int, optional
  
          :param max_width:
              Maximum number of characters in a line to render node attributes.
          :type max_width: int, optional
  
          :param view:
              Open the main page of the site?
          :type view: bool, optional
  
          :return:
              A SiteMap.
          :rtype: schedula.utils.drw.SiteMap
  
          Example:
  
          .. dispatcher:: dsp
             :opt: graph_attr={'ratio': '1'}
             :code:
  
              >>> from schedula import Dispatcher
              >>> dsp = Dispatcher(name='Dispatcher')
              >>> def fun(a):
              ...     return a + 1, a - 1
              >>> dsp.add_function('fun', fun, ['a'], ['b', 'c'])
              'fun'
              >>> dsp.plot(view=False, graph_attr={'ratio': '1'})
              SiteMap([(Dispatcher, SiteMap())])
          """
  
          d = {
              'name': name, 'comment': comment, 'format': format,
              'engine': engine, 'encoding': encoding, 'graph_attr': graph_attr,
              'node_attr': node_attr, 'edge_attr': edge_attr, 'body': body,
          }
          options = {
              'digraph': {k: v for k, v in d.items() if v is not NONE} or NONE,
              'node_styles': node_styles,
              'node_data': node_data,
              'node_function': node_function,
              'edge_data': edge_data,
              'max_lines': max_lines,  # 5
              'max_width': max_width,  # 200
          }
          options = {k: v for k, v in options.items() if v is not NONE}
          from .drw import SiteMap
          from .sol import Solution
  
          if workflow is None and isinstance(self, Solution):
              workflow = True
          else:
              workflow = workflow or False
  
          sitemap = SiteMap()
          sitemap.add_items(self, workflow=workflow, depth=depth, **options)
          if view:
              import tempfile
              directory = directory or tempfile.mkdtemp()
              if sites is None:
                  sitemap.render(directory=directory, view=True, index=index)
              else:
                  sites.add(sitemap.site(directory, view=True, index=index))
          return sitemap