docs: def gdfs_to_graph(gdf_nodes, gdf_edges):
      """
      Convert node and edge GeoDataFrames into a graph
  
      Parameters
      ----------
      gdf_nodes : GeoDataFrame
      gdf_edges : GeoDataFrame
  
      Returns
      -------
      networkx multidigraph
      """
  
      G = nx.MultiDiGraph()
      G.graph['crs'] = gdf_nodes.crs
      G.graph['name'] = gdf_nodes.gdf_name.rstrip('_nodes')
  
      # add the nodes and their attributes to the graph
      G.add_nodes_from(gdf_nodes.index)
      attributes = gdf_nodes.to_dict()
      for attribute_name in gdf_nodes.columns:
          # only add this attribute to nodes which have a non-null value for it
          attribute_values = {k:v for k, v in attributes[attribute_name].items() if pd.notnull(v)}
          nx.set_node_attributes(G, name=attribute_name, values=attribute_values)
  
      # add the edges and attributes that are not u, v, key (as they're added
      # separately) or null
      for _, row in gdf_edges.iterrows():
          attrs = {}
          for label, value in row.iteritems():
              if (label not in ['u', 'v', 'key']) and (isinstance(value, list) or pd.notnull(value)):
                  attrs[label] = value
          G.add_edge(row['u'], row['v'], key=row['key'], **attrs)
  
      return G