class_docstr: A custom Figure class to make waffle charts.
  
  :param values: Numerical value of each category. If it is a dict, the keys would be used as labels.
  :type values: list|dict|pandas.Series
  
  :param rows: The number of lines of the waffle chart.
  :type rows: int
  
  :param columns: The number of columns of the waffle chart.
  
      | At least one of rows and columns is required.
      | If either rows or columns is passed, the other parameter would be calculated automatically through the absolute value of values.
      | If both of rows and columns are passed, the block number is fixed and block numbers are calculated from scaled values.
  :type columns: int
  
  :param colors: A list of colors for each category. Its length should be the same as values.
  
      | Default values are from Set2 colormap.
  :type colors: list[str]|tuple[str], optional
  
  :param labels: The name of each category.
  
      | If the values is a dict, this parameter would be replaced by the keys of values.
  :type labels: list[str]|tuple[str], optional
  
  :param legend: Parameters of matplotlib.pyplot.legend in a dict.
  
      | E.g. {'loc': '', 'bbox_to_anchor': (,), ...}
      | See full parameter list in https://matplotlib.org/api/_as_gen/matplotlib.pyplot.legend.html
  :type legend: dict, optional
  
  :param interval_ratio_x: Ratio of horizontal distance between blocks to block's width. [Default 0.2]
  :type interval_ratio_x: float, optional
  
  :param interval_ratio_y: Ratio of vertical distance between blocks to block's height. [Default 0.2]
  :type interval_ratio_y: float, optional
  
  :param block_aspect_ratio: The ratio of block's width to height. [Default 1]
  :type block_aspect_ratio: float, optional
  
  :param cmap_name: Name of colormaps for default color, if colors is not assigned.
  
      | See full list in https://matplotlib.org/examples/color/colormaps_reference.html
      | [Default 'Set2']
  :type cmap_name: str, optional
  
  :param title: Parameters of matplotlib.axes.Axes.set_title in a dict.
  
      | E.g. {'label': '', 'fontdict': {}, 'loc': ''}
      | See full parameter list in https://matplotlib.org/api/_as_gen/matplotlib.pyplot.title.html
  :type title: dict, optional
  
  :param characters: A character in string or a list of characters for each category. [Default None]
  :type icons: str|list[str]|tuple[str], optional
  
  :param font_size: Font size of Font Awesome icons.
  
      | The default size is not fixed and depends on the block size.
      | Either an relative value of 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large' or an absolute font size.
  :type icons: int|str, optional
  
  :param font_file: Path to custom font file.
  :type icons: str, optional
  
  :param icons: Icon name of Font Awesome.
  
      | If it is a string, all categories use the same icon;
      | If it's a list or tuple of icons, the length should be the same as values.
      | See the full list of Font Awesome on https://fontawesome.com/icons?d=gallery&m=free
      | [Default None]
  :type icons: str|list[str]|tuple[str], optional
  
  :param icon_style: The style of icons to be used.
  
      | Font Awesome Icons find an icon by style and icon name.
      The style could be 'brands', 'regular' and 'solid'.
      Visit https://fontawesome.com/cheatsheet for detail.
  
      | If it is a string, it would search icons within given style.
      If it is a list or a tuple, the length should be
      the same as values and it means the style for each icon.
  
      | [Default 'solid']
  :type icon_style: str|list[str]|tuple[str], optional
  
  :param icon_size: Font size of Font Awesome icons.
  
      | Deprecated! Use font_size instead.
      | The default size is not fixed and depends on the block size.
      | Either an relative value of 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large' or an absolute value of font size.
  :type icon_size: int|str, optional
  
  :param icon_legend: Whether to use icon but not color bar in legend. [Default False]
  :type icon_legend: bool, optional
  
  :param plot_anchor: The alignment method of subplots. ``{'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}``
  
      | See details in https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.set_anchor.html
      | [Default 'W']
  :type plot_anchor: str, optional
  
  :param plots: Position and parameters of Waffle class for subplots in a dict,
      with format like {pos: {subplot_args: values, }, }.
  
      | Pos could be a tuple of three integer, where the first digit is the number of rows, the second the number of columns, and the third the index of the subplot.
      | Pos could also be a 3-digit number in int or string type. For example, it accept 235 or '235' standing for the Ith plot on a grid with J rows and K columns. Note that all integers must be less than 10 for this form to work.
      | The parameters of subplots are the same as Waffle class parameters, excluding plots itself.
      | If any parameter of subplots is not assigned, it use the same parameter in Waffle class as default value.
  :type plots: dict, optional
  
  :param vertical: Whether to draw the plot vertically or horizontally. [Default False]
  :type vertical: bool, optional
  
  :param starting_location: Change the starting location plotting the blocks. ``{'NW', 'SW', 'NE', 'SE'}``
  
      | When it's 'NW', it means plots start from upper-left; 'SW' means plots start from lower-left; 'NE' means plots start from upper-right; 'SE' means plots start from lower-right.
      | [Default 'SW']
  :type starting_location: str, optional
  
  :param rounding_rule: The rounding rule applied when adjusting values to fit the chart size. ``{'nearest', 'floor', 'ceil'}``
  
      | When it's 'nearest', it is "round to nearest, ties to even" rounding mode;
      | When it's 'floor', it rounds to less of the two endpoints of the interval;
      | When it's 'ceil', it rounds to greater of the two endpoints of the interval.
      | [Default 'nearest']
  :type rounding_rule: str, optional
  
  :param tight: Set whether and how `.tight_layout` is called when drawing.
  
      | It could be bool or dict with keys "pad", "w_pad", "h_pad", "rect" or None
      | If a bool, sets whether to call `.tight_layout` upon drawing.
      | If ``None``, use the ``figure.autolayout`` param instead.
      | If a dict, pass it as kwargs to `.tight_layout`, overriding the default paddings.
      | [Default True]
  :type tight: bool|dict, optional
  
  :param block_arranging_style: Set how to arrange blocks. ``{'normal', 'snake', 'new-line'}``
  
      | If it is 'normal', it draws blocks line by line with same direction.
      | If it is 'snake', it draws blocks with snake pattern.
      | If it is 'new-line', it starts with a new line when drawing each category. This only works when only one of ``rows`` and ``columns`` is assigned, and ``vertical=False`` when ``rows`` is assigned or ``vertical=True`` when ``rows`` is assigned.
      | [Default 'normal']
  :type block_arranging_style: string, optional
code: def __init__(self, *args, **kwargs):
      #:All Waffle-specific arguments with default values
      self.fig_args: Dict = self._kwarg_processor(
          kwargs=kwargs, default_values=self._default_parameters
      )
      super().__init__(*args, **kwargs)
  
      #:Standardized arguments of all subplots
      self.plot_args: List = []
  
      #:The length of values
      self.values_len: Optional[int] = None
  
      plots = self.fig_args["plots"] or {} or {111: self.fig_args}
  
      for loc, plot_args in plots.items():
          # Add subplots
          if isinstance(loc, tuple):
              ax = self.add_subplot(*loc, aspect="equal")
          elif isinstance(loc, (int, str)):
              ax = self.add_subplot(loc, aspect="equal")
          else:
              raise TypeError(
                  "Subplot position should be tuple, int, or string."
              )
  
          self._make_single_waffle(
              ax=ax, fig_args=self.fig_args, plot_args=plot_args
          )
  
      # Adjust the layout
      self.set_tight_layout(self.fig_args["tight"])
  
imports: import copy
  import math
  from itertools import islice, product
  from typing import Dict, Iterable, Iterator, List, Optional, Tuple, Union
  import warnings
  import matplotlib.font_manager
  from matplotlib.axes import Axes
  from matplotlib.figure import Figure
  from matplotlib.patches import Patch, Rectangle
  from matplotlib.pyplot import cm
label_desc: Use image node_id 1 to create a new Waffle object from inherited base classes: Figure with example: obj = Waffle()