code: def concrete_bipartite_as_graph(self, subjects, patterns) -> Graph:  # pragma: no cover
          
          if Graph is None:
              raise ImportError('The graphviz package is required to draw the graph.')
          bipartite = self._build_bipartite(subjects, patterns)
          graph = Graph()
          nodes_left = {}  # type: Dict[TLeft, str]
          nodes_right = {}  # type: Dict[TRight, str]
          node_id = 0
          for (left, right), value in bipartite._edges.items():
              if left not in nodes_left:
                  subject_id, i = left
                  name = 'node{:d}'.format(node_id)
                  nodes_left[left] = name
                  label = '{}, {}'.format(i, self.subjects_by_id[subject_id])
                  graph.node(name, label=label)
                  node_id += 1
              if right not in nodes_right:
                  pattern, i = right
                  name = 'node{:d}'.format(node_id)
                  nodes_right[right] = name
                  label = '{}, {}'.format(i, self.automaton.patterns[pattern][0])
                  graph.node(name, label=label)
                  node_id += 1
              edge_label = value is not True and str(value) or ''
              graph.edge(nodes_left[left], nodes_right[right], edge_label)
          return graph
docs: Returns a :class:`graphviz.Graph` representation of this bipartite graph.