code: def draw_networkx_edges(
      G,
      pos,
      edgelist=None,
      width=1.0,
      edge_color="k",
      style="solid",
      alpha=1.0,
      arrowstyle="-|>",
      arrowsize=10,
      edge_cmap=None,
      edge_vmin=None,
      edge_vmax=None,
      ax=None,
      arrows=True,
      label=None,
      node_size=300,
      nodelist=None,
      node_shape="o",
      connectionstyle="arc3",
      **kwds,
  ):
      """Draw the edges of the graph G.
  
      This draws only the edges of the graph G.
  
      Parameters
      ----------
      G : graph
         A networkx graph
  
      pos : dictionary
         A dictionary with nodes as keys and positions as values.
         Positions should be sequences of length 2.
  
      edgelist : collection of edge tuples
         Draw only specified edges(default=G.edges())
  
      width : float, or array of floats
         Line width of edges (default=1.0)
  
      edge_color : color string, or array of floats
         Edge color. Can be a single color format string (default='r'),
         or a sequence of colors with the same length as edgelist.
         If numeric values are specified they will be mapped to
         colors using the edge_cmap and edge_vmin,edge_vmax parameters.
  
      style : string
         Edge line style (default='solid') (solid|dashed|dotted,dashdot)
  
      alpha : float
         The edge transparency (default=1.0)
  
      edge_ cmap : Matplotlib colormap
         Colormap for mapping intensities of edges (default=None)
  
      edge_vmin,edge_vmax : floats
         Minimum and maximum for edge colormap scaling (default=None)
  
      ax : Matplotlib Axes object, optional
         Draw the graph in the specified Matplotlib axes.
  
      arrows : bool, optional (default=True)
         For directed graphs, if True draw arrowheads.
         Note: Arrows will be the same color as edges.
  
      arrowstyle : str, optional (default='-|>')
         For directed graphs, choose the style of the arrow heads.
         See :py:class: `matplotlib.patches.ArrowStyle` for more
         options.
  
      arrowsize : int, optional (default=10)
         For directed graphs, choose the size of the arrow head head's length and
         width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute
         `mutation_scale` for more info.
  
      label : [None| string]
         Label for legend
  
      Returns
      -------
      matplotlib.collection.LineCollection
          `LineCollection` of the edges
  
      list of matplotlib.patches.FancyArrowPatch
          `FancyArrowPatch` instances of the directed edges
  
      Depending whether the drawing includes arrows or not.
  
      Notes
      -----
      For directed graphs, arrows are drawn at the head end.  Arrows can be
      turned off with keyword arrows=False. Be sure to include `node_size' as a
      keyword argument; arrows are drawn considering the size of nodes.
  
      Examples
      --------
      >>> G = nx.dodecahedral_graph()
      >>> edges = nx.draw_networkx_edges(G, pos=nx.spring_layout(G))
  
      >>> G = nx.DiGraph()
      >>> G.add_edges_from([(1, 2), (1, 3), (2, 3)])
      >>> arcs = nx.draw_networkx_edges(G, pos=nx.spring_layout(G))
      >>> alphas = [0.3, 0.4, 0.5]
      >>> for i, arc in enumerate(arcs):  # change alpha values of arcs
      ...     arc.set_alpha(alphas[i])
  
      Also see the NetworkX drawing examples at
      https://networkx.github.io/documentation/latest/auto_examples/index.html
  
      See Also
      --------
      draw()
      draw_networkx()
      draw_networkx_nodes()
      draw_networkx_labels()
      draw_networkx_edge_labels()
      """
      try:
          import matplotlib
          import matplotlib.cbook as cb
          import matplotlib.pyplot as plt
          import numpy as np
          from matplotlib.collections import LineCollection
          from matplotlib.colors import (
              colorConverter,
              Colormap,
              Normalize,
          )
          from matplotlib.patches import (
              ConnectionStyle,
              FancyArrowPatch,
          )
      except ImportError:
          raise ImportError("Matplotlib required for draw()")
      except RuntimeError:
          print("Matplotlib unable to open display")
          raise
  
      if ax is None:
          ax = plt.gca()
  
      if edgelist is None:
          edgelist = list(G.edges())
  
      if not edgelist or len(edgelist) == 0:  # no edges!
          return None
  
      if nodelist is None:
          nodelist = list(G.nodes())
  
      # set edge positions
      edge_pos = np.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])
  
      if not cb.iterable(width):
          lw = (width,)
      else:
          lw = width
  
      if (
          not is_string_like(edge_color)
          and cb.iterable(edge_color)
          and len(edge_color) == len(edge_pos)
      ):
          if np.alltrue([is_string_like(c) for c in edge_color]):
              # (should check ALL elements)
              # list of color letters such as ['k','r','k',...]
              edge_colors = tuple(
                  [colorConverter.to_rgba(c, alpha) for c in edge_color]
              )
          elif np.alltrue([not is_string_like(c) for c in edge_color]):
              # If color specs are given as (rgb) or (rgba) tuples, we're OK
              if np.alltrue(
                  [
                      cb.iterable(c) and len(c) in (3, 4)
                      for c in edge_color
                  ]
              ):
                  edge_colors = tuple(edge_color)
              else:
                  # numbers (which are going to be mapped with a colormap)
                  edge_colors = None
          else:
              raise ValueError(
                  "edge_color must contain color names or numbers"
              )
      else:
          if is_string_like(edge_color) or len(edge_color) == 1:
              edge_colors = (colorConverter.to_rgba(edge_color, alpha),)
          else:
              msg = "edge_color must be a color or list of one color per edge"
              raise ValueError(msg)
  
      if not G.is_directed() or not arrows:
          edge_collection = LineCollection(
              edge_pos,
              colors=edge_colors,
              linewidths=lw,
              antialiaseds=(1,),
              linestyle=style,
              transOffset=ax.transData,
          )
  
          edge_collection.set_zorder(1)  # edges go behind nodes
          edge_collection.set_label(label)
          ax.add_collection(edge_collection)
  
          # Note: there was a bug in mpl regarding the handling of alpha values
          # for each line in a LineCollection. It was fixed in matplotlib by
          # r7184 and r7189 (June 6 2009). We should then not set the alpha
          # value globally, since the user can instead provide per-edge alphas
          # now.  Only set it globally if provided as a scalar.
          if cb.is_numlike(alpha):
              edge_collection.set_alpha(alpha)
  
          if edge_colors is None:
              if edge_cmap is not None:
                  assert isinstance(edge_cmap, Colormap)
              edge_collection.set_array(np.asarray(edge_color))
              edge_collection.set_cmap(edge_cmap)
              if edge_vmin is not None or edge_vmax is not None:
                  edge_collection.set_clim(edge_vmin, edge_vmax)
              else:
                  edge_collection.autoscale()
          return edge_collection
  
      arrow_collection = None
  
      if G.is_directed() and arrows:
          # Note: Waiting for someone to implement arrow to intersection with
          # marker.  Meanwhile, this works well for polygons with more than 4
          # sides and circle.
  
          def to_marker_edge(marker_size, marker):
              if marker in "s^>v<d":  # `large` markers need extra space
                  return np.sqrt(2 * marker_size) / 2
              else:
                  return np.sqrt(marker_size) / 2
  
          # Draw arrows with `matplotlib.patches.FancyarrowPatch`
          arrow_collection = []
          mutation_scale = arrowsize  # scale factor of arrow head
          arrow_colors = edge_colors
          if arrow_colors is None:
              if edge_cmap is not None:
                  assert isinstance(edge_cmap, Colormap)
              else:
                  edge_cmap = (
                      plt.get_cmap()
                  )  # default matplotlib colormap
              if edge_vmin is None:
                  edge_vmin = min(edge_color)
              if edge_vmax is None:
                  edge_vmax = max(edge_color)
              color_normal = Normalize(vmin=edge_vmin, vmax=edge_vmax)
  
          for i, (src, dst) in enumerate(edge_pos):
              x1, y1 = src
              x2, y2 = dst
              arrow_color = None
              line_width = None
              shrink_source = 0  # space from source to tail
              shrink_target = 0  # space from  head to target
              if cb.iterable(node_size):  # many node sizes
                  src_node, dst_node = edgelist[i]
                  index_node = nodelist.index(dst_node)
                  marker_size = node_size[index_node]
                  shrink_target = to_marker_edge(
                      marker_size, node_shape
                  )
              else:
                  shrink_target = to_marker_edge(node_size, node_shape)
              if arrow_colors is None:
                  arrow_color = edge_cmap(color_normal(edge_color[i]))
              elif len(arrow_colors) > 1:
                  arrow_color = arrow_colors[i]
              else:
                  arrow_color = arrow_colors[0]
              if len(lw) > 1:
                  line_width = lw[i]
              else:
                  line_width = lw[0]
              arrow = FancyArrowPatch(
                  (x1, y1),
                  (x2, y2),
                  arrowstyle=arrowstyle,
                  shrinkA=shrink_source,
                  shrinkB=shrink_target,
                  mutation_scale=mutation_scale,
                  connectionstyle=connectionstyle,
                  color=arrow_color,
                  linewidth=line_width,
                  zorder=1,
              )  # arrows go behind nodes
  
              # There seems to be a bug in matplotlib to make collections of
              # FancyArrowPatch instances. Until fixed, the patches are added
              # individually to the axes instance.
              arrow_collection.append(arrow)
              ax.add_patch(arrow)
  
      # update view
      minx = np.amin(np.ravel(edge_pos[:, :, 0]))
      maxx = np.amax(np.ravel(edge_pos[:, :, 0]))
      miny = np.amin(np.ravel(edge_pos[:, :, 1]))
      maxy = np.amax(np.ravel(edge_pos[:, :, 1]))
  
      w = maxx - minx
      h = maxy - miny
      padx, pady = 0.05 * w, 0.05 * h
      corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
      ax.update_datalim(corners)
      ax.autoscale_view()
  
      return arrow_collection
  
file_path: dgl/examples/pytorch/transformer/modules/viz.py
imports: import os
  import matplotlib
  import matplotlib.animation
  import matplotlib.pyplot
  import networkx
  import numpy
  import torch
  from networkx.algorithms import bipartite
  import networkx
  from matplotlib.patches import ConnectionStyle, FancyArrowPatch
  from networkx.utils import is_string_like
label_desc: Use image node_id 6 for calling a global function with example usage: draw_networkx_edges(G, pos, edgelist, width, edge_color, style, alpha, arrowstyle, arrowsize, edge_cmap, edge_vmin, edge_vmax, ax, arrows, label, node_size, nodelist, node_shape, connectionstyle) and returns: arrow_collection, None, edge_collection, unknown, unknown