  
          self._visible_grid, self._visible_faces = self._grid.visible_area
          if (isinstance(self._images, np.ndarray) and isinstance(self._visible_grid, np.ndarray)
                  and self._visible_grid.shape[-1] != self._images.shape[-1]):
              self._recycle_objects()
  
          required_rows = self._visible_grid.shape[1] if self._grid.is_valid else 0
          existing_rows = len(self._images)
          logger.trace("existing_rows: %s. required_rows: %s", existing_rows, required_rows)
  
 
</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         if point_x > self._grid.dimensions[0]:
 </s> add         if not self._grid.is_valid or point_x > self._grid.dimensions[0]: </s> remove         logger.debug("existing rows: %s, required_rows: %s, base_coords: %s",
 </s> add         logger.trace("existing rows: %s, required_rows: %s, base_coords: %s", </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)
            self._reset_viewport()
  
          self._visible_grid, self._visible_faces = self._grid.visible_area
          if (isinstance(self._images, np.ndarray) and isinstance(self._visible_grid, np.ndarray)
                  and self._visible_grid.shape[-1] != self._images.shape[-1]):
            self._reset_viewport()
  
          required_rows = self._visible_grid.shape[1] if self._grid.is_valid else 0
          existing_rows = len(self._images)
          logger.trace("existing_rows: %s. required_rows: %s", existing_rows, required_rows)
  
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