docs: def plot_figure_ground(G=None, address=None, point=None, dist=805,
                         network_type='drive_service', street_widths=None,
                         default_width=4, fig_length=8, edge_color='w',
                         bgcolor='#333333', smooth_joints=True, filename=None,
                         file_format='png', show=False, save=True, close=True,
                         dpi=300):
      """
      Plot a figure-ground diagram of a street network, defaulting to one square
      mile.
  
      Parameters
      ----------
      G : networkx multidigraph
      address : string
          the address to geocode as the center point if G is not passed in
      point : tuple
          the center point if address and G are not passed in
      dist : numeric
          how many meters to extend north, south, east, and west from the center
          point
      network_type : string
          what type of network to get
      street_widths : dict
          where keys are street types and values are widths to plot in pixels
      default_width : numeric
          the default street width in pixels for any street type not found in
          street_widths dict
      fig_length : numeric
          the height and width of this square diagram
      edge_color : string
          the color of the streets
      bgcolor : string
          the color of the background
      smooth_joints : bool
          if True, plot nodes same width as streets to smooth line joints and
          prevent cracks between them from showing
      filename : string
          filename to save the image as
      file_format : string
          the format of the file to save (e.g., 'jpg', 'png', 'svg')
      show : bool
          if True, show the figure
      save : bool
          if True, save the figure as an image file to disk
      close : bool
          close the figure (only if show equals False) to prevent display
      dpi : int
          the resolution of the image file if saving
  
      Returns
      -------
      fig, ax : tuple
      """
  
      multiplier = 1.2
  
      # if G was passed-in, use this graph in the plot, centered on the centroid
      # of its nodes
      if G is not None:
          gdf_nodes = graph_to_gdfs(G, edges=False, node_geometry=True)
          lnglat_point = gdf_nodes.unary_union.centroid.coords[0]
          point = tuple(reversed(lnglat_point))
  
      # otherwise, get the network by either address or point, whichever was
      # passed-in, using a distance multiplier to make sure we get more than
      # enough network. simplify in non-strict mode to not combine multiple street
      # types into single edge
      elif address is not None:
          G, point = graph_from_address(address, distance=dist*multiplier, distance_type='bbox', network_type=network_type,
                                        simplify=False, truncate_by_edge=True, return_coords=True)
          G = simplify_graph(G, strict=False)
      elif point is not None:
          G = graph_from_point(point, distance=dist*multiplier, distance_type='bbox', network_type=network_type,
                               simplify=False, truncate_by_edge=True)
          G = simplify_graph(G, strict=False)
      else:
          raise ValueError('You must pass an address or lat-long point or graph.')
  
      # if user did not pass in custom street widths, create a dict of default
      # values
      if street_widths is None:
          street_widths = {'footway' : 1.5,
                           'steps' : 1.5,
                           'pedestrian' : 1.5,
                           'service' : 1.5,
                           'path' : 1.5,
                           'track' : 1.5,
                           'motorway' : 6}
  
      # we need an undirected graph to find every edge incident to a node
      G_undir = G.to_undirected()
  
      # for each network edge, get a linewidth according to street type (the OSM
      # 'highway' value)
      edge_linewidths = []
      for _, _, data in G_undir.edges(keys=False, data=True):
          street_type = data['highway'][0] if isinstance(data['highway'], list) else data['highway']
          if street_type in street_widths:
              edge_linewidths.append(street_widths[street_type])
          else:
              edge_linewidths.append(default_width)
  
      if smooth_joints:
          # for each node, get a nodesize according to the narrowest incident edge
          node_widths = {}
          for node in G_undir.nodes():
              # first, identify all the highway types of this node's incident edges
              incident_edges_data = [G_undir.get_edge_data(node, neighbor) for neighbor in G_undir.neighbors(node)]
              edge_types = [data[0]['highway'] for data in incident_edges_data]
              if len(edge_types) < 1:
                  # if node has no incident edges, make size zero
                  node_widths[node] = 0
              else:
                  # flatten the list of edge types
                  edge_types_flat = []
                  for et in edge_types:
                      if isinstance(et, list):
                          edge_types_flat.extend(et)
                      else:
                          edge_types_flat.append(et)
  
                  # for each edge type in the flattened list, lookup the
                  # corresponding width
                  edge_widths = [street_widths[edge_type] if edge_type in street_widths else default_width for edge_type in edge_types_flat]
  
                  # the node diameter will be the biggest of the edge widths, to make joints perfectly smooth
                  # alternatively, use min (?) to pervent anything larger from extending past smallest street's line
                  circle_diameter = max(edge_widths)
  
                  # mpl circle marker sizes are in area, so it is the diameter
                  # squared
                  circle_area = circle_diameter ** 2
                  node_widths[node] = circle_area
  
          # assign the node size to each node in the graph
          node_sizes = [node_widths[node] for node in G_undir.nodes()]
      else:
          node_sizes = 0
  
      # define the spatial extents of the plotting figure to make it square, in
      # projected units, and cropped to the desired area
      bbox = bbox_from_point(point, dist, project_utm=False)
  
      # create a filename if one was not passed
      if filename is None and save:
          filename = 'figure_ground_{}_{}'.format(point, network_type)
  
      # plot the figure
      fig, ax = plot_graph(G_undir, bbox=bbox, fig_height=fig_length,
                           margin=0, axis_off=True, equal_aspect=False,
                           bgcolor=bgcolor, node_size=node_sizes,
                           node_color=edge_color, edge_linewidth=edge_linewidths,
                           edge_color=edge_color, show=show, save=save,
                           close=close, filename=filename, file_format=file_format,
                           dpi=dpi)
  
      return fig, ax