code: def to_networkx(
      g,
      node_attrs=None,
      edge_attrs=None,
      ntype_attr="ntype",
      etype_attr="etype",
      eid_attr="id",
  ):
      """Convert a graph to a NetworkX graph and return.
  
      The resulting NetworkX graph also contains the node/edge features of the input graph.
      Additionally, DGL saves the edge IDs as the ``'id'`` edge attribute in the
      returned NetworkX graph.
  
      Parameters
      ----------
      g : DGLGraph
          A homogeneous or heterogeneous graph.
      node_attrs : iterable of str, optional
          The node attributes to copy from ``g.ndata``. (Default: None)
      edge_attrs : iterable of str, optional
          The edge attributes to copy from ``g.edata``.
          (Default: None)
      ntype_attr : str, optional
          The name of the node attribute to store the node types in the NetworkX object.
          (Default: "ntype")
      etype_attr : str, optional
          The name of the edge attribute to store the edge canonical types in the NetworkX object.
          (Default: "etype")
      eid_attr : str, optional
          The name of the edge attribute to store the original edge ID in the NetworkX object.
          (Default: "id")
  
      Returns
      -------
      networkx.DiGraph
          The converted NetworkX graph.
  
      Notes
      -----
      The function only supports CPU graph input.
  
      Examples
      --------
      The following examples use the PyTorch backend.
  
      >>> import dgl
      >>> import torch
  
      With a homogeneous graph:
  
      >>> g = dgl.graph((torch.tensor([1, 2]), torch.tensor([1, 3])))
      >>> g.ndata['h'] = torch.zeros(4, 1)
      >>> g.edata['h1'] = torch.ones(2, 1)
      >>> g.edata['h2'] = torch.zeros(2, 2)
      >>> nx_g = dgl.to_networkx(g, node_attrs=['h'], edge_attrs=['h1', 'h2'])
      >>> nx_g.nodes(data=True)
      NodeDataView({
          0: {'h': tensor([0.])},
          1: {'h': tensor([0.])},
          2: {'h': tensor([0.])},
          3: {'h': tensor([0.])}
      })
      >>> nx_g.edges(data=True)
      OutMultiEdgeDataView([
          (1, 1, {'id': 0, 'h1': tensor([1.]), 'h2': tensor([0., 0.])}),
          (2, 3, {'id': 1, 'h1': tensor([1.]), 'h2': tensor([0., 0.])})
      ])
  
      With a heterogeneous graph:
  
      >>> g = dgl.heterograph({
      ...     ('user', 'follows', 'user'): (torch.tensor([0, 1]), torch.tensor([1, 2])),
      ...     ('user', 'follows', 'topic'): (torch.tensor([1, 1]), torch.tensor([1, 2])),
      ...     ('user', 'plays', 'game'): (torch.tensor([0, 3]), torch.tensor([3, 4]))
      ... })
      ... g.ndata['n'] = {
      ...     'game': torch.zeros(5, 1),
      ...     'user': torch.ones(4, 1)
      ... }
      ... g.edata['e'] = {
      ...     ('user', 'follows', 'user'): torch.zeros(2, 1),
      ...     'plays': torch.ones(2, 1)
      ... }
      >>> nx_g = dgl.to_networkx(g, node_attrs=['n'], edge_attrs=['e'])
      >>> nx_g.nodes(data=True)
      NodeDataView({
          0: {'ntype': 'game', 'n': tensor([0.])},
          1: {'ntype': 'game', 'n': tensor([0.])},
          2: {'ntype': 'game', 'n': tensor([0.])},
          3: {'ntype': 'game', 'n': tensor([0.])},
          4: {'ntype': 'game', 'n': tensor([0.])},
          5: {'ntype': 'topic'},
          6: {'ntype': 'topic'},
          7: {'ntype': 'topic'},
          8: {'ntype': 'user', 'n': tensor([1.])},
          9: {'ntype': 'user', 'n': tensor([1.])},
          10: {'ntype': 'user', 'n': tensor([1.])},
          11: {'ntype': 'user', 'n': tensor([1.])}
      })
      >>> nx_g.edges(data=True)
      OutMultiEdgeDataView([
          (8, 9, {'id': 2, 'etype': ('user', 'follows', 'user'), 'e': tensor([0.])}),
          (8, 3, {'id': 4, 'etype': ('user', 'plays', 'game'), 'e': tensor([1.])}),
          (9, 6, {'id': 0, 'etype': ('user', 'follows', 'topic')}),
          (9, 7, {'id': 1, 'etype': ('user', 'follows', 'topic')}),
          (9, 10, {'id': 3, 'etype': ('user', 'follows', 'user'), 'e': tensor([0.])}),
          (11, 4, {'id': 5, 'etype': ('user', 'plays', 'game'), 'e': tensor([1.])})
      ])
      """
      if g.device != F.cpu():
          raise DGLError(
              "Cannot convert a CUDA graph to networkx. Call g.cpu() first."
          )
      if g.is_homogeneous:
          return _to_networkx_homogeneous(g, node_attrs, edge_attrs)
      else:
          return _to_networkx_heterogeneous(
              g,
              node_attrs,
              edge_attrs,
              ntype_attr,
              etype_attr,
              eid_attr,
          )
  
imports: from collections import defaultdict
  from collections.abc import Mapping
  import networkx
  import numpy
  from scipy.sparse import spmatrix
  from .None import backend, graph_index, heterograph_index, utils
  from .base import DGLError, EID, ETYPE, NID, NTYPE
  from .heterograph import combine_frames, DGLBlock, DGLGraph
label_desc: Use image node_id 15 for calling a global function with example usage: to_networkx(g, node_attrs, edge_attrs, ntype_attr, etype_attr, eid_attr) and returns: _to_networkx_homogeneous, _to_networkx_heterogeneous