class_docstr: Represents the layout of a graph.
  
  A layout is practically a list of coordinates in an n-dimensional
  space. This class is generic in the sense that it can store coordinates
  in any n-dimensional space.
  
  Layout objects are not associated directly with a graph. This is deliberate:
  there were times when I worked with almost identical copies of the same
  graph, the only difference was that they had different colors assigned to
  the vertices. It was particularly convenient for me to use the same layout
  for all of them, especially when I made figures for a paper. However,
  C{igraph} will of course refuse to draw a graph with a layout that has
  less coordinates than the node count of the graph.
  
  Layouts behave exactly like lists when they are accessed using the item
  index operator (C{[...]}). They can even be iterated through. Items
  returned by the index operator are only copies of the coordinates,
  but the stored coordinates can be modified by directly assigning to
  an index.
  
      >>> layout = Layout([(0, 1), (0, 2)])
      >>> coords = layout[1]
      >>> print(coords)
      [0, 2]
      >>> coords = (0, 3)
      >>> print(layout[1])
      [0, 2]
      >>> layout[1] = coords
      >>> print(layout[1])
      [0, 3]
docstr: Fits the layout into the given bounding box.
  
  The layout will be modified in-place.
  
  @param bbox: the bounding box in which to fit the layout. If the
    dimension of the layout is d, it can either be a d-tuple (defining
    the sizes of the box), a 2d-tuple (defining the coordinates of the
    top left and the bottom right point of the box), or a L{BoundingBox}
    object (for 2D layouts only).
  @param keep_aspect_ratio: whether to keep the aspect ratio of the current
    layout. If C{False}, the layout will be rescaled to fit exactly into
    the bounding box. If C{True}, the original aspect ratio of the layout
    will be kept and it will be centered within the bounding box.
docstr_tok: ["Fits","the","layout","into","the","given","bounding","box",".","The","layout","will","be","modified","in-place",".","@","param","bbox",":","the","bounding","box","in","which","to","fit","the","layout",".","If","the","dimension","of","the","layout","is","d",",","it","can","either","be","a","d-tuple","(","defining","the","sizes","of","the","box",")",",","a","2d-tuple","(","defining","the","coordinates","of","the","top","left","and","the","bottom","right","point","of","the","box",")",",","or","a","L","{","BoundingBox","}","object","(","for","2D","layouts","only",")",".","@","param","keep_aspect_ratio",":","whether","to","keep","the","aspect","ratio","of","the","current","layout",".","If","C","{","False","}",",","the","layout","will","be","rescaled","to","fit","exactly","into","the","bounding","box",".","If","C","{","True","}",",","the","original","aspect","ratio","of","the","layout","will","be","kept","and","it","will","be","centered","within","the","bounding","box","."]
code: def fit_into(self, bbox, keep_aspect_ratio=True):
      """Fits the layout into the given bounding box.
  
      The layout will be modified in-place.
  
      @param bbox: the bounding box in which to fit the layout. If the
        dimension of the layout is d, it can either be a d-tuple (defining
        the sizes of the box), a 2d-tuple (defining the coordinates of the
        top left and the bottom right point of the box), or a L{BoundingBox}
        object (for 2D layouts only).
      @param keep_aspect_ratio: whether to keep the aspect ratio of the current
        layout. If C{False}, the layout will be rescaled to fit exactly into
        the bounding box. If C{True}, the original aspect ratio of the layout
        will be kept and it will be centered within the bounding box.
      """
      if isinstance(bbox, BoundingBox):
          if self._dim != 2:
              raise TypeError("bounding boxes work for 2D layouts only")
          corner, target_sizes = [bbox.left, bbox.top], [
              bbox.width,
              bbox.height,
          ]
      elif len(bbox) == self._dim:
          corner, target_sizes = [0.0] * self._dim, list(bbox)
      elif len(bbox) == 2 * self._dim:
          corner, opposite_corner = list(bbox[0 : self._dim]), list(
              bbox[self._dim :]
          )
          for i in range(self._dim):
              if corner[i] > opposite_corner[i]:
                  corner[i], opposite_corner[i] = (
                      opposite_corner[i],
                      corner[i],
                  )
          target_sizes = [
              max_val - min_val
              for min_val, max_val in zip(corner, opposite_corner)
          ]
  
      try:
          mins, maxs = self.boundaries()
      except ValueError:
          mins, maxs = [0.0] * self._dim, [0.0] * self._dim
      sizes = [
          max_val - min_val for min_val, max_val in zip(mins, maxs)
      ]
  
      for i, size in enumerate(sizes):
          if size == 0:
              sizes[i] = 2
              mins[i] -= 1
              maxs[i] += 1
  
      ratios = [
          float(target_size) / current_size
          for current_size, target_size in zip(sizes, target_sizes)
      ]
      if keep_aspect_ratio:
          min_ratio = min(ratios)
          ratios = [min_ratio] * self._dim
  
      translations = []
      for i in range(self._dim):
          trans = (target_sizes[i] - ratios[i] * sizes[i]) / 2.0
          trans -= mins[i] * ratios[i] - corner[i]
          translations.append(trans)
  
      self.scale(*ratios)
      self.translate(*translations)
  
imports: from math import sin, cos, pi
  from igraph._igraph import GraphBase
  from igraph.drawing.utils import BoundingBox
  from igraph.statistics import RunningMean
label_desc: Use image node_id 22 for calling the Layout obj's underlying member method code with example usage: obj.fit_into(bbox, keep_aspect_ratio) without return types