docs: def plot_footprints(gdf, fig=None, ax=None, figsize=None, color='#333333', bgcolor='w',
                     set_bounds=True, bbox=None, save=False, show=True, close=False, 
                     filename='image', file_format='png', dpi=600):
      """
      Plot a GeoDataFrame of footprints.
  
      Parameters
      ----------
      gdf : GeoDataFrame
          footprints
      fig : figure
      ax : axis
      figsize : tuple
      color : string
          the color of the footprints
      bgcolor : string
          the background color of the plot
      set_bounds : bool
          if True, set bounds from either passed-in bbox or the spatial extent of the gdf
      bbox : tuple
          if True and if set_bounds is True, set the display bounds to this bbox
      save : bool
          whether to save the figure to disk or not
      show : bool
          whether to display the figure or not
      close : bool
          close the figure (only if show equals False) to prevent display
      filename : string
          the name of the file to save
      file_format : string
          the format of the file to save (e.g., 'jpg', 'png', 'svg')
      dpi : int
          the resolution of the image file if saving
  
      Returns
      -------
      fig, ax : tuple
  
      """
  
      if fig is None or ax is None:
          fig, ax = plt.subplots(figsize=figsize, facecolor=bgcolor)
          ax.set_facecolor(bgcolor)
  
      # extract each polygon as a descartes patch, and add to a matplotlib patch
      # collection
      patches = []
      for geometry in gdf['geometry']:
          if isinstance(geometry, Polygon):
              patches.append(PolygonPatch(geometry))
          elif isinstance(geometry, MultiPolygon):
              for subpolygon in geometry: #if geometry is multipolygon, go through each constituent subpolygon
                  patches.append(PolygonPatch(subpolygon))
      pc = PatchCollection(patches, facecolor=color, edgecolor=color, linewidth=0, alpha=1)
      ax.add_collection(pc)
  
      if set_bounds:
          if bbox is None:
              # set the figure bounds to the polygons' bounds
              left, bottom, right, top = gdf.total_bounds
          else:
              top, bottom, right, left = bbox
          ax.set_xlim((left, right))
          ax.set_ylim((bottom, top))
  
      # turn off the axis display set the margins to zero and point the ticks in
      # so there's no space around the plot
      ax.axis('off')
      ax.margins(0)
      ax.tick_params(which='both', direction='in')
      fig.canvas.draw()
  
      # make everything square
      ax.set_aspect('equal')
      fig.canvas.draw()
  
      fig, ax = save_and_show(fig=fig, ax=ax, save=save, show=show, close=close,
                              filename=filename, file_format=file_format, dpi=dpi, axis_off=True)
  
      return fig, ax