class_docstr: Place a legend on the figure/axes.
class_docstr_tok: ["Place","a","legend","on","the","figure\/axes","."]
docstr: Parameters
  ----------
  parent : `~matplotlib.axes.Axes` or `.Figure`
      The artist that contains the legend.
  
  handles : list of (`.Artist` or tuple of `.Artist`)
      A list of Artists (lines, patches) to be added to the legend.
  
  labels : list of str
      A list of labels to show next to the artists. The length of handles
      and labels should be the same. If they are not, they are truncated
      to the length of the shorter list.
  
  Other Parameters
  ----------------
  %(_legend_kw_doc)s
  
  Attributes
  ----------
  legend_handles
      List of `.Artist` objects added as legend entries.
  
      .. versionadded:: 3.7
docstr_tok: ["Parameters","--","--","--","--","--","parent",":","`","~matplotlib.axes.Axes","`","or","`",".Figure","`","The","artist","that","contains","the","legend",".","handles",":","list","of","(","`",".Artist","`","or","tuple","of","`",".Artist","`",")","A","list","of","Artists","(","lines",",","patches",")","to","be","added","to","the","legend",".","labels",":","list","of","str","A","list","of","labels","to","show","next","to","the","artists",".","The","length","of","handles","and","labels","should","be","the","same",".","If","they","are","not",",","they","are","truncated","to","the","length","of","the","shorter","list",".","Other","Parameters","--","--","--","--","--","--","--","--","%","(","_legend_kw_doc",")","s","Attributes","--","--","--","--","--","legend_handles","List","of","`",".Artist","`","objects","added","as","legend","entries",".","..","versionadded",":",":","3.7"]
code: def __init__(
      self,
      parent,
      handles,
      labels,
      *,
      loc=None,
      numpoints=None,  # number of points in the legend line
      markerscale=None,  # relative size of legend markers vs. original
      markerfirst=True,  # left/right ordering of legend marker and label
      reverse=False,  # reverse ordering of legend marker and label
      scatterpoints=None,  # number of scatter points
      scatteryoffsets=None,
      prop=None,  # properties for the legend texts
      fontsize=None,  # keyword to set font size directly
      labelcolor=None,  # keyword to set the text color
      # spacing & pad defined as a fraction of the font-size
      borderpad=None,  # whitespace inside the legend border
      labelspacing=None,  # vertical space between the legend entries
      handlelength=None,  # length of the legend handles
      handleheight=None,  # height of the legend handles
      handletextpad=None,  # pad between the legend handle and text
      borderaxespad=None,  # pad between the axes and legend border
      columnspacing=None,  # spacing between columns
      ncols=1,  # number of columns
      mode=None,  # horizontal distribution of columns: None or "expand"
      fancybox=None,  # True: fancy box, False: rounded box, None: rcParam
      shadow=None,
      title=None,  # legend title
      title_fontsize=None,  # legend title font size
      framealpha=None,  # set frame alpha
      edgecolor=None,  # frame patch edgecolor
      facecolor=None,  # frame patch facecolor
      bbox_to_anchor=None,  # bbox to which the legend will be anchored
      bbox_transform=None,  # transform for the bbox
      frameon=None,  # draw frame
      handler_map=None,
      title_fontproperties=None,  # properties for the legend title
      alignment="center",  # control the alignment within the legend box
      ncol=1,  # synonym for ncols (backward compatibility)
      draggable=False,  # whether the legend can be dragged with the mouse
  ):
      """
      Parameters
      ----------
      parent : `~matplotlib.axes.Axes` or `.Figure`
          The artist that contains the legend.
  
      handles : list of (`.Artist` or tuple of `.Artist`)
          A list of Artists (lines, patches) to be added to the legend.
  
      labels : list of str
          A list of labels to show next to the artists. The length of handles
          and labels should be the same. If they are not, they are truncated
          to the length of the shorter list.
  
      Other Parameters
      ----------------
      %(_legend_kw_doc)s
  
      Attributes
      ----------
      legend_handles
          List of `.Artist` objects added as legend entries.
  
          .. versionadded:: 3.7
      """
      # local import only to avoid circularity
      from matplotlib.axes import Axes
      from matplotlib.figure import FigureBase
  
      super().__init__()
  
      if prop is None:
          self.prop = FontProperties(
              size=mpl._val_or_rc(fontsize, "legend.fontsize")
          )
      else:
          self.prop = FontProperties._from_any(prop)
          if isinstance(prop, dict) and "size" not in prop:
              self.prop.set_size(mpl.rcParams["legend.fontsize"])
  
      self._fontsize = self.prop.get_size_in_points()
  
      self.texts = []
      self.legend_handles = []
      self._legend_title_box = None
  
      #: A dictionary with the extra handler mappings for this Legend
      #: instance.
      self._custom_handler_map = handler_map
  
      self.numpoints = mpl._val_or_rc(numpoints, "legend.numpoints")
      self.markerscale = mpl._val_or_rc(
          markerscale, "legend.markerscale"
      )
      self.scatterpoints = mpl._val_or_rc(
          scatterpoints, "legend.scatterpoints"
      )
      self.borderpad = mpl._val_or_rc(borderpad, "legend.borderpad")
      self.labelspacing = mpl._val_or_rc(
          labelspacing, "legend.labelspacing"
      )
      self.handlelength = mpl._val_or_rc(
          handlelength, "legend.handlelength"
      )
      self.handleheight = mpl._val_or_rc(
          handleheight, "legend.handleheight"
      )
      self.handletextpad = mpl._val_or_rc(
          handletextpad, "legend.handletextpad"
      )
      self.borderaxespad = mpl._val_or_rc(
          borderaxespad, "legend.borderaxespad"
      )
      self.columnspacing = mpl._val_or_rc(
          columnspacing, "legend.columnspacing"
      )
      self.shadow = mpl._val_or_rc(shadow, "legend.shadow")
      # trim handles and labels if illegal label...
      _lab, _hand = [], []
      for label, handle in zip(labels, handles):
          if isinstance(label, str) and label.startswith("_"):
              _api.warn_deprecated(
                  "3.8",
                  message=(
                      "An artist whose label starts with an underscore was passed to "
                      "legend(); such artists will no longer be ignored in the future.  "
                      "To suppress this warning, explicitly filter out such artists, "
                      "e.g. with `[art for art in artists if not "
                      "art.get_label().startswith('_')]`."
                  ),
              )
          else:
              _lab.append(label)
              _hand.append(handle)
      labels, handles = _lab, _hand
  
      if reverse:
          labels.reverse()
          handles.reverse()
  
      if len(handles) < 2:
          ncols = 1
      self._ncols = ncols if ncols != 1 else ncol
  
      if self.numpoints <= 0:
          raise ValueError(
              "numpoints must be > 0; it was %d" % numpoints
          )
  
      # introduce y-offset for handles of the scatter plot
      if scatteryoffsets is None:
          self._scatteryoffsets = np.array(
              [3.0 / 8.0, 4.0 / 8.0, 2.5 / 8.0]
          )
      else:
          self._scatteryoffsets = np.asarray(scatteryoffsets)
      reps = self.scatterpoints // len(self._scatteryoffsets) + 1
      self._scatteryoffsets = np.tile(self._scatteryoffsets, reps)[
          : self.scatterpoints
      ]
  
      # _legend_box is a VPacker instance that contains all
      # legend items and will be initialized from _init_legend_box()
      # method.
      self._legend_box = None
  
      if isinstance(parent, Axes):
          self.isaxes = True
          self.axes = parent
          self.set_figure(parent.figure)
      elif isinstance(parent, FigureBase):
          self.isaxes = False
          self.set_figure(parent)
      else:
          raise TypeError(
              "Legend needs either Axes or FigureBase as parent"
          )
      self.parent = parent
  
      self._mode = mode
      self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
  
      # Figure out if self.shadow is valid
      # If shadow was None, rcParams loads False
      # So it shouldn't be None here
  
      self._shadow_props = {
          "ox": 2,
          "oy": -2,
      }  # default location offsets
      if isinstance(self.shadow, dict):
          self._shadow_props.update(self.shadow)
          self.shadow = True
      elif self.shadow in (0, 1, True, False):
          self.shadow = bool(self.shadow)
      else:
          raise ValueError(
              "Legend shadow must be a dict or bool, not "
              f"{self.shadow!r} of type {type(self.shadow)}."
          )
  
      # We use FancyBboxPatch to draw a legend frame. The location
      # and size of the box will be updated during the drawing time.
  
      facecolor = mpl._val_or_rc(facecolor, "legend.facecolor")
      if facecolor == "inherit":
          facecolor = mpl.rcParams["axes.facecolor"]
  
      edgecolor = mpl._val_or_rc(edgecolor, "legend.edgecolor")
      if edgecolor == "inherit":
          edgecolor = mpl.rcParams["axes.edgecolor"]
  
      fancybox = mpl._val_or_rc(fancybox, "legend.fancybox")
  
      self.legendPatch = FancyBboxPatch(
          xy=(0, 0),
          width=1,
          height=1,
          facecolor=facecolor,
          edgecolor=edgecolor,
          # If shadow is used, default to alpha=1 (#8943).
          alpha=(
              framealpha
              if framealpha is not None
              else 1
              if shadow
              else mpl.rcParams["legend.framealpha"]
          ),
          # The width and height of the legendPatch will be set (in draw())
          # to the length that includes the padding. Thus we set pad=0 here.
          boxstyle=(
              "round,pad=0,rounding_size=0.2"
              if fancybox
              else "square,pad=0"
          ),
          mutation_scale=self._fontsize,
          snap=True,
          visible=mpl._val_or_rc(frameon, "legend.frameon"),
      )
      self._set_artist_props(self.legendPatch)
  
      _api.check_in_list(
          ["center", "left", "right"], alignment=alignment
      )
      self._alignment = alignment
  
      # init with null renderer
      self._init_legend_box(handles, labels, markerfirst)
  
      # Set legend location
      self.set_loc(loc)
  
      # figure out title font properties:
      if (
          title_fontsize is not None
          and title_fontproperties is not None
      ):
          raise ValueError(
              "title_fontsize and title_fontproperties can't be specified "
              "at the same time. Only use one of them. "
          )
      title_prop_fp = FontProperties._from_any(title_fontproperties)
      if isinstance(title_fontproperties, dict):
          if "size" not in title_fontproperties:
              title_fontsize = mpl.rcParams["legend.title_fontsize"]
              title_prop_fp.set_size(title_fontsize)
      elif title_fontsize is not None:
          title_prop_fp.set_size(title_fontsize)
      elif not isinstance(title_fontproperties, FontProperties):
          title_fontsize = mpl.rcParams["legend.title_fontsize"]
          title_prop_fp.set_size(title_fontsize)
  
      self.set_title(title, prop=title_prop_fp)
  
      self._draggable = None
      self.set_draggable(state=draggable)
  
      # set the text color
  
      color_getters = {  # getter function depends on line or patch
          "linecolor": ["get_color", "get_facecolor"],
          "markerfacecolor": ["get_markerfacecolor", "get_facecolor"],
          "mfc": ["get_markerfacecolor", "get_facecolor"],
          "markeredgecolor": ["get_markeredgecolor", "get_edgecolor"],
          "mec": ["get_markeredgecolor", "get_edgecolor"],
      }
      labelcolor = mpl._val_or_rc(labelcolor, "legend.labelcolor")
      if labelcolor is None:
          labelcolor = mpl.rcParams["text.color"]
      if isinstance(labelcolor, str) and labelcolor in color_getters:
          getter_names = color_getters[labelcolor]
          for handle, text in zip(self.legend_handles, self.texts):
              try:
                  if handle.get_array() is not None:
                      continue
              except AttributeError:
                  pass
              for getter_name in getter_names:
                  try:
                      color = getattr(handle, getter_name)()
                      if isinstance(color, np.ndarray):
                          if (
                              color.shape[0] == 1
                              or np.isclose(color, color[0]).all()
                          ):
                              text.set_color(color[0])
                          else:
                              pass
                      else:
                          text.set_color(color)
                      break
                  except AttributeError:
                      pass
      elif isinstance(labelcolor, str) and labelcolor == "none":
          for text in self.texts:
              text.set_color(labelcolor)
      elif np.iterable(labelcolor):
          for text, color in zip(
              self.texts,
              itertools.cycle(colors.to_rgba_array(labelcolor)),
          ):
              text.set_color(color)
      else:
          raise ValueError(f"Invalid labelcolor: {labelcolor!r}")
  
imports: import itertools
  import logging
  import numbers
  import time
  import numpy
  import matplotlib
  from matplotlib import _api, _docstring, colors, offsetbox
  from matplotlib.artist import Artist, allow_rasterization
  from matplotlib.cbook import silent_list
  from matplotlib.font_manager import FontProperties
  from matplotlib.lines import Line2D
  from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch, StepPatch
  from matplotlib.collections import Collection, CircleCollection, LineCollection, PathCollection, PolyCollection, RegularPolyCollection
  from matplotlib.text import Text
  from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
  from matplotlib.transforms import BboxTransformTo, BboxTransformFrom
  from matplotlib.offsetbox import AnchoredOffsetbox, DraggableOffsetBox, HPacker, VPacker, DrawingArea, TextArea
  from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer
  from .None import legend_handler
label_desc: Use image node_id 2 to create a new Legend object from inherited base classes: Artist with example: obj = Legend(parent, handles, labels)