          if not isinstance(self._images, np.ndarray):
              base_coords = [(col * self._size, 0) for col in range(columns)]
          else:
              base_coords = [self._canvas.coords(item_id) for item_id in self._images[0]]
          logger.debug("existing rows: %s, required_rows: %s, base_coords: %s",
                       existing_rows, required_rows, base_coords)
          images = []
          meshes = []
          for row in range(existing_rows, required_rows):
              y_coord = base_coords[0][1] + (row * self._size)
 
</s> remove         self._images = []
        self._meshes = []
 </s> add     def _remove_rows(self, existing_rows, required_rows):
        """ Remove and recycle rows from the viewport that are not in the view area.

        Parameters
        ----------
        existing_rows: int
            The number of existing rows within the viewport
        required_rows: int
            The number of rows required by the viewport
        """
        logger.debug("Removing rows from viewport: (existing_rows: %s, required_rows: %s)",
                     existing_rows, required_rows)
        self._recycle_objects(self._images[required_rows: existing_rows].flatten().tolist(),
                              self._meshes[required_rows: existing_rows].flatten().tolist())
        self._images = self._images[:required_rows]
        self._meshes = self._meshes[:required_rows]
        logger.trace("self._images: %s, self._meshes: %s",
                     self._images.shape, self._meshes.shape) </s> remove             for image_id, mesh_ids in zip(self._images[required_rows: existing_rows].flatten(),
                                          self._meshes[required_rows: existing_rows].flatten()):
                logger.trace("Hiding image id: %s", image_id)
                self._canvas.itemconfig(image_id, image="")
                for ids in mesh_ids.values():
                    for mesh_id in ids:
                        self._canvas.itemconfig(mesh_id, state="hidden")

 </s> add             self._remove_rows(existing_rows, required_rows) </s> remove         logger.trace("visible: %s", visible)
 </s> add         logger.trace("height: %s, yview: %s, face_size: %s, visible: %s",
                     height, self._canvas.yview(), self._face_size, visible)
        logger.trace("existing rows: %s, required_rows: %s, base_coords: %s",
          if not isinstance(self._images, np.ndarray):
              base_coords = [(col * self._size, 0) for col in range(columns)]
          else:
              base_coords = [self._canvas.coords(item_id) for item_id in self._images[0]]
        logger.trace("existing rows: %s, required_rows: %s, base_coords: %s",
                       existing_rows, required_rows, base_coords)
          images = []
          meshes = []
          for row in range(existing_rows, required_rows):
              y_coord = base_coords[0][1] + (row * self._size)
keep keep keep keep replace keep keep keep keep keep
 Bugfix - Manual Tool
  - Fix non-appearing landmark annotations in face viewer 
tools/manual/faceviewer/viewport.py