code: def render_graph(
      graph_specification: dict, render_distributions: bool = False
  ) -> "graphviz.Digraph":
      """
      Create a graphviz object given a graph specification.
  
      :param bool render_distributions: Show distribution of each RV in plot.
      """
      try:
          import graphviz  # noqa: F401
      except ImportError as e:
          raise ImportError(
              "Looks like you want to use graphviz (https://graphviz.org/) "
              "to render your model. "
              "You need to install `graphviz` to be able to use this feature. "
              "It can be installed with `pip install graphviz`."
          ) from e
  
      plate_groups = graph_specification["plate_groups"]
      plate_data = graph_specification["plate_data"]
      node_data = graph_specification["node_data"]
      edge_list = graph_specification["edge_list"]
  
      graph = graphviz.Digraph()
  
      # add plates
      plate_graph_dict = {
          plate: graphviz.Digraph(name=f"cluster_{plate}")
          for plate in plate_groups
          if plate is not None
      }
      for plate, plate_graph in plate_graph_dict.items():
          plate_graph.attr(
              label=plate.split("__CLONE")[0],
              labeljust="r",
              labelloc="b",
          )
  
      plate_graph_dict[None] = graph
  
      # add nodes
      colors = {False: "white", True: "gray", None: "gray:white"}
      for plate, rv_list in plate_groups.items():
          cur_graph = plate_graph_dict[plate]
  
          for rv in rv_list:
              color = colors[node_data[rv]["is_observed"]]
  
              # For sample_nodes - ellipse
              if node_data[rv]["distribution"]:
                  shape = "ellipse"
                  rv_label = rv
  
              # For param_nodes - No shape
              else:
                  shape = "plain"
                  rv_label = rv.replace("$params", "")
  
              # use different symbol for Deterministic site
              node_style = (
                  "filled,dashed"
                  if node_data[rv]["distribution"] == "Deterministic"
                  else "filled"
              )
              cur_graph.node(
                  rv,
                  label=rv_label,
                  shape=shape,
                  style=node_style,
                  fillcolor=color,
              )
  
      # add leaf nodes first
      while len(plate_data) >= 1:
          for plate, data in plate_data.items():
              parent_plate = data["parent"]
              is_leaf = True
  
              for plate2, data2 in plate_data.items():
                  if plate == data2["parent"]:
                      is_leaf = False
                      break
  
              if is_leaf:
                  plate_graph_dict[parent_plate].subgraph(
                      plate_graph_dict[plate]
                  )
                  plate_data.pop(plate)
                  break
  
      # add edges
      for source, target in edge_list:
          graph.edge(source, target)
  
      # render distributions if requested
      if render_distributions:
          dist_label = ""
          for rv, data in node_data.items():
              rv_dist = data["distribution"]
              if rv_dist:
                  dist_label += rf"{rv} ~ {rv_dist}\l"
  
              if "constraint" in data and data["constraint"]:
                  dist_label += rf"{rv} : {data['constraint']}\l"
  
          graph.node(
              "distribution_description_node",
              label=dist_label,
              shape="plaintext",
          )
  
      # return whole graph
      return graph
  
imports: import itertools
  import os
  from collections import defaultdict
  from pathlib import Path
  from types import SimpleNamespace
  from typing import Callable, Collection, Dict, List, Optional, Union
  import torch
  import pyro
  import pyro.distributions
  import pyro.poutine
  from pyro.ops.provenance import ProvenanceTensor, detach_provenance, get_provenance
  from pyro.poutine.messenger import Messenger
  from pyro.poutine.util import site_is_subsample
label_desc: Use image node_id 8 for calling a global function with example usage: render_graph(graph_specification, render_distributions) and returns: graph