class_docstr: Analogous to a gridspec, and contained in another LayoutGrid.
class_docstr_tok: ["Analogous","to","a","gridspec",",","and","contained","in","another","LayoutGrid","."]
code: def __init__(
      self,
      parent=None,
      parent_pos=(0, 0),
      parent_inner=False,
      name="",
      ncols=1,
      nrows=1,
      h_pad=None,
      w_pad=None,
      width_ratios=None,
      height_ratios=None,
  ):
      Variable = kiwi.Variable
      self.parent_pos = parent_pos
      self.parent_inner = parent_inner
      self.name = name + seq_id()
      if isinstance(parent, LayoutGrid):
          self.name = f"{parent.name}.{self.name}"
      self.nrows = nrows
      self.ncols = ncols
      self.height_ratios = np.atleast_1d(height_ratios)
      if height_ratios is None:
          self.height_ratios = np.ones(nrows)
      self.width_ratios = np.atleast_1d(width_ratios)
      if width_ratios is None:
          self.width_ratios = np.ones(ncols)
  
      sn = self.name + "_"
      if not isinstance(parent, LayoutGrid):
          # parent can be a rect if not a LayoutGrid
          # allows specifying a rectangle to contain the layout.
          self.solver = kiwi.Solver()
      else:
          parent.add_child(self, *parent_pos)
          self.solver = parent.solver
      # keep track of artist associated w/ this layout.  Can be none
      self.artists = np.empty((nrows, ncols), dtype=object)
      self.children = np.empty((nrows, ncols), dtype=object)
  
      self.margins = {}
      self.margin_vals = {}
      # all the boxes in each column share the same left/right margins:
      for todo in ["left", "right", "leftcb", "rightcb"]:
          # track the value so we can change only if a margin is larger
          # than the current value
          self.margin_vals[todo] = np.zeros(ncols)
  
      sol = self.solver
  
      self.lefts = [Variable(f"{sn}lefts[{i}]") for i in range(ncols)]
      self.rights = [Variable(f"{sn}rights[{i}]") for i in range(ncols)]
      for todo in ["left", "right", "leftcb", "rightcb"]:
          self.margins[todo] = [
              Variable(f"{sn}margins[{todo}][{i}]")
              for i in range(ncols)
          ]
          for i in range(ncols):
              sol.addEditVariable(self.margins[todo][i], "strong")
  
      for todo in ["bottom", "top", "bottomcb", "topcb"]:
          self.margins[todo] = np.empty((nrows), dtype=object)
          self.margin_vals[todo] = np.zeros(nrows)
  
      self.bottoms = [
          Variable(f"{sn}bottoms[{i}]") for i in range(nrows)
      ]
      self.tops = [Variable(f"{sn}tops[{i}]") for i in range(nrows)]
      for todo in ["bottom", "top", "bottomcb", "topcb"]:
          self.margins[todo] = [
              Variable(f"{sn}margins[{todo}][{i}]")
              for i in range(nrows)
          ]
          for i in range(nrows):
              sol.addEditVariable(self.margins[todo][i], "strong")
  
      # set these margins to zero by default. They will be edited as
      # children are filled.
      self.reset_margins()
      self.add_constraints(parent)
  
      self.h_pad = h_pad
      self.w_pad = w_pad
  
imports: import itertools
  import kiwisolver
  import logging
  import numpy
  import matplotlib
  import matplotlib.patches
  from matplotlib.transforms import Bbox
label_desc: Use image node_id 1 to create a new LayoutGrid object  with example: obj = LayoutGrid(parent, parent_pos, parent_inner, name, ncols, nrows, h_pad, w_pad, width_ratios, height_ratios)