code: def plot_gdf(
      layer: str,
      gdf: gp.GeoDataFrame,
      ax: matplotlib.axes.Axes,
      mode: str = "matplotlib",
      # vsk: Optional[vsketch.SketchClass] = None,
      vsk=None,
      palette: Optional[List[str]] = None,
      width: Optional[Union[dict, float]] = None,
      union: bool = False,
      dilate_points: Optional[float] = None,
      dilate_lines: Optional[float] = None,
      **kwargs,
  ) -> None:
      """
      Plot a layer
  
      Args:
          layer (str): layer name
          gdf (gp.GeoDataFrame): GeoDataFrame
          ax (matplotlib.axes.Axes): matplotlib axis object
          mode (str): drawing mode. Options: 'matplotlib', 'vsketch'. Defaults to 'matplotlib'
          vsk (Optional[vsketch.SketchClass]): Vsketch object. Mandatory if mode == 'plotter'
          palette (Optional[List[str]], optional): Color palette. Defaults to None.
          width (Optional[Union[dict, float]], optional): Street widths. Either a dictionary or a float. Defaults to None.
          union (bool, optional): Whether to join geometries. Defaults to False.
          dilate_points (Optional[float], optional): Amount of dilation to be applied to point (1D) geometries. Defaults to None.
          dilate_lines (Optional[float], optional): Amount of dilation to be applied to line (2D) geometries. Defaults to None.
  
      Raises:
          Exception: _description_
      """
  
      # Get hatch and hatch_c parameter
      hatch_c = kwargs.pop("hatch_c") if "hatch_c" in kwargs else None
  
      # Convert GDF to shapely geometries
      geometries = gdf_to_shapely(
          layer,
          gdf,
          width,
          point_size=dilate_points,
          line_width=dilate_lines,
      )
      geometries = (
          geometries.geoms
          if isinstance(geometries, Iterable)
          else [geometries]
      )
  
      # Unite geometries
      if union:
          geometries = shapely.ops.unary_union(geometries)
  
      if (
          (palette is None)
          and ("fc" in kwargs)
          and (type(kwargs["fc"]) != str)
      ):
          palette = kwargs.pop("fc")
  
      # Plot shapes
      for shape in geometries:
          if mode == "matplotlib":
              if type(shape) in [Polygon, MultiPolygon]:
                  # Plot main shape (without silhouette)
                  ax.add_patch(
                      PolygonPatch(
                          shape,
                          lw=0,
                          ec=hatch_c
                          if hatch_c
                          else kwargs["ec"]
                          if "ec" in kwargs
                          else None,
                          fc=kwargs["fc"]
                          if "fc" in kwargs
                          else np.random.choice(palette)
                          if palette
                          else None,
                          **{
                              k: v
                              for k, v in kwargs.items()
                              if k not in ["lw", "ec", "fc"]
                          },
                      ),
                  )
                  # Plot just silhouette
                  ax.add_patch(
                      PolygonPatch(
                          shape,
                          fill=False,
                          **{
                              k: v
                              for k, v in kwargs.items()
                              if k not in ["hatch", "fill"]
                          },
                      )
                  )
              elif type(shape) == LineString:
                  ax.plot(
                      *shape.xy,
                      c=kwargs["ec"] if "ec" in kwargs else None,
                      **{
                          k: v
                          for k, v in kwargs.items()
                          if k in ["lw", "lt", "dashes", "zorder"]
                      },
                  )
              elif type(shape) == MultiLineString:
                  for c in shape.geoms:
                      ax.plot(
                          *c.xy,
                          c=kwargs["ec"] if "ec" in kwargs else None,
                          **{
                              k: v
                              for k, v in kwargs.items()
                              if k in ["lw", "lt", "dashes", "zorder"]
                          },
                      )
          elif mode == "plotter":
              if ("draw" not in kwargs) or kwargs["draw"]:
                  # Set stroke
                  if "stroke" in kwargs:
                      vsk.stroke(kwargs["stroke"])
                  else:
                      vsk.stroke(1)
  
                  # Set pen width
                  if "penWidth" in kwargs:
                      vsk.penWidth(kwargs["penWidth"])
                  else:
                      vsk.penWidth(0.3)
  
                  if "fill" in kwargs:
                      vsk.fill(kwargs["fill"])
                  else:
                      vsk.noFill()
  
                  vsk.geometry(shape)
          else:
              raise Exception(f"Unknown mode {mode}")
  
imports: import re
  import os
  import json
  import yaml
  import pathlib
  import warnings
  import matplotlib
  import shapely.ops
  import numpy
  import osmnx
  import pandas
  import geopandas
  import shapely.affinity
  from copy import deepcopy
  from .fetch import get_gdfs
  from dataclasses import dataclass
  from matplotlib import pyplot
  from matplotlib.colors import hex2color
  from matplotlib.patches import Path, PathPatch
  from typing import Optional, Union, Tuple, List, Dict, Any, Iterable
  from shapely.geometry.base import BaseGeometry
  from shapely.geometry import Point, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection, box
label_desc: Use image node_id 3 for calling a global function with example usage: plot_gdf(layer, gdf, ax, mode, vsk, palette, width, union, dilate_points, dilate_lines) without return types