code: def plot(
      # Your query. Example:
      # - "Porto Alegre"
      # - (-30.0324999, -51.2303767) (lat/long coordinates)
      # - You can also provide a custom GeoDataFrame boundary as input
      query: Union[str, Tuple[float, float], gp.GeoDataFrame],
      # Which OpenStreetMap layers to plot
      # Example: {'building': {'tags': {'building': True}}, 'streets': {'width': 2}}
      # Run prettymaps.presets() for more examples
      layers={},
      # Matplotlib params for drawing each layer
      style={},
      # Whether to load params from preset
      preset="default",
      # Whether to save preset
      save_preset=None,
      # Whether to load and update preset with additional parameters
      update_preset=None,
      # Custom postprocessing function on layers
      postprocessing=None,
      # Circular boundary? Default: square
      circle=None,
      # Radius for circular or square boundary
      radius=None,
      # Dilate boundary by this much
      dilate=None,
      # Whether to save result
      save_as=None,
      # Figure parameters
      fig=None,
      ax=None,
      title=None,
      figsize=(12, 12),
      constrained_layout=True,
      # Credit message parameters
      credit={},
      # Mode ('matplotlib' or 'plotter')
      mode="matplotlib",
      # Multiplot mode
      multiplot=False,
      # Whether to display matplotlib
      show=True,
      # Transform (translation, scale, rotation) parameters
      x=0,
      y=0,
      scale_x=1,
      scale_y=1,
      rotation=0,
  ):
      """
  
      Draw a map from OpenStreetMap data.
  
      Parameters
      ----------
      query : string
          The address to geocode and use as the central point around which to get the geometries
      backup : dict
          (Optional) feed the output from a previous 'plot()' run to save time
      postprocessing: function
          (Optional) Apply a postprocessing step to the 'layers' dict
      radius
          (Optional) If not None, draw the map centered around the address with this radius (in meters)
      layers: dict
          Specify the name of each layer and the OpenStreetMap tags to fetch
      style: dict
          Drawing params for each layer (matplotlib params such as 'fc', 'ec', 'fill', etc.)
      osm_credit: dict
          OSM Caption parameters
      figsize: Tuple
          (Optional) Width and Height (in inches) for the Matplotlib figure. Defaults to (10, 10)
      ax: axes
          Matplotlib axes
      title: String
          (Optional) Title for the Matplotlib figure
      vsketch: Vsketch
          (Optional) Vsketch object for pen plotting
      x: float
          (Optional) Horizontal displacement
      y: float
          (Optional) Vertical displacement
      scale_x: float
          (Optional) Horizontal scale factor
      scale_y: float
          (Optional) Vertical scale factor
      rotation: float
          (Optional) Rotation in angles (0-360)
  
      Returns
      -------
      layers: dict
          Dictionary of layers (each layer is a Shapely MultiPolygon)
  
      Notes
      -----
  
      """
  
      # 1. Manage presets
      layers, style, circle, radius, dilate = manage_presets(
          preset,
          save_preset,
          update_preset,
          layers,
          style,
          circle,
          radius,
          dilate,
      )
  
      # 2. Init matplotlib figure
      if (mode == "matplotlib") and (ax is None):
          fig = plt.figure(figsize=figsize)
          ax = plt.subplot(111, aspect="equal")
  
      # 3. Override arguments in layers' kwargs dict
      layers = override_args(layers, circle, dilate)
  
      # 4. Fetch geodataframes
      gdfs = get_gdfs(query, layers, radius, dilate, -rotation)
  
      # 5. Apply transformations to GeoDataFrames (translation, scale, rotation)
      gdfs = transform_gdfs(gdfs, x, y, scale_x, scale_y, rotation)
  
      # 6. Apply a postprocessing function to the GeoDataFrames, if provided
      if postprocessing:
          gdfs = postprocessing(gdfs)
  
      # 7. Create background GeoDataFrame and get (x,y) bounds
      background, xmin, ymin, xmax, ymax, dx, dy = create_background(
          gdfs, style
      )
  
      # 8. Draw layers
      if mode == "plotter":
          # 8.1. Draw layers in plotter (vsketch) mode
          """
          class Sketch(vsketch.SketchClass):
  
              def draw(self, vsk: vsketch.Vsketch):
  
                  vsk.size("a4", landscape=True)
  
                  for layer in gdfs:
                      if layer in layers:
                          plot_gdf(
                              layer,
                              gdfs[layer],
                              ax,
                              width=layers[layer]["width"]
                              if "width" in layers[layer]
                              else None,
                              mode=mode,
                              vsk=vsk,
                              **(style[layer] if layer in style else {}),
                          )
  
                  if save_as:
                      vsk.save(save_as)
  
              def finalize(self, vsk: vsketch.Vsketch):
                  vsk.vpype("linemerge linesimplify reloop linesort")
  
          sketch = Sketch()
          sketch.display()
          """
      elif mode == "matplotlib":
          # 8.2. Draw layers in matplotlib mode
          for layer in gdfs:
              if layer in layers:
                  plot_gdf(
                      layer,
                      gdfs[layer],
                      ax,
                      width=layers[layer]["width"]
                      if "width" in layers[layer]
                      else None,
                      **(style[layer] if layer in style else {}),
                  )
      else:
          raise Exception(f"Unknown mode {mode}")
  
      # 9. Draw background
      if "background" in style:
          zorder = (
              style["background"].pop("zorder")
              if "zorder" in style["background"]
              else -1
          )
          ax.add_patch(
              PolygonPatch(
                  background,
                  **{
                      k: v
                      for k, v in style["background"].items()
                      if k != "dilate"
                  },
                  zorder=zorder,
              )
          )
  
      # 10. Draw credit message
      if (
          (mode == "matplotlib")
          and (credit != False)
          and (not multiplot)
      ):
          draw_text(credit, background)
  
      # 11. Ajust figure and create PIL Image
      if mode == "matplotlib":
          # Adjust axis
          ax.axis("off")
          ax.axis("equal")
          ax.autoscale()
          # Adjust padding
          plt.subplots_adjust(
              left=0, bottom=0, right=1, top=1, wspace=0, hspace=0
          )
          # Save result
          if save_as:
              plt.savefig(save_as)
          if not show:
              plt.close()
  
      return Plot(gdfs, fig, ax, background)
  
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 20 for calling a global function with example usage: plot(query, layers, style, preset, save_preset, update_preset, postprocessing, circle, radius, dilate, save_as, fig, ax, title, figsize, constrained_layout, credit, mode, multiplot, show, x, y, scale_x, scale_y, rotation) and returns: Plot