      @property
      def _top_left(self):
          """ :class:`numpy.ndarray`: The canvas (`x`, `y`) position of the face currently in the
          viewable area's top left position. """
          return np.array(self._canvas.coords(self._images[0][0]), dtype="int")
  
      def update(self):
          """ Load and unload thumbnails in the visible area of the faces viewer. """
          if self._canvas.optional_annotations["mesh"]:  # Display any hidden end of row meshes
              self._canvas.itemconfig("viewport_mesh", state="normal")
 
</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     def _recycle_objects(self):
        """  On a column count change, place all existing objects into the recycle bin so that
        they can be used for the new grid shape and reset the objects size to the new size. """
 </s> add     def _reset_viewport(self):
        """ Reset all objects in the viewport on a column count change. Reset the viewport size
        to the newly specified face size. """
        logger.debug("Resetting Viewport") </s> remove                                                    refresh=refresh_annotations)
 </s> add                                                    refresh=True)
        if self._images is None or not np.any(self._images):
            retval = [0, 0]
        else:
            retval = self._canvas.coords(self._images[0][0])
        return np.array(retval, dtype="int")
      @property
      def _top_left(self):
          """ :class:`numpy.ndarray`: The canvas (`x`, `y`) position of the face currently in the
          viewable area's top left position. """
        if self._images is None or not np.any(self._images):
            retval = [0, 0]
        else:
            retval = self._canvas.coords(self._images[0][0])
        return np.array(retval, dtype="int")
  
      def update(self):
          """ Load and unload thumbnails in the visible area of the faces viewer. """
          if self._canvas.optional_annotations["mesh"]:  # Display any hidden end of row meshes
              self._canvas.itemconfig("viewport_mesh", state="normal")
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