diff --git a/src/aliby/io/image.py b/src/aliby/io/image.py
index 5af04ca679d92fe9d40ca33f029b9553f42a9dc2..42005645b6935e07ff264f8e4b699258d2c75d37 100644
--- a/src/aliby/io/image.py
+++ b/src/aliby/io/image.py
@@ -29,15 +29,11 @@ from tifffile import TiffFile
 from agora.io.metadata import dir_to_meta, dispatch_metadata_parser
 
 
-def get_examples_dir():
-    """Get examples directory that stores dummy image for tiler."""
-    return files("aliby").parent.parent / "examples" / "tiler"
-
-
 def instantiate_image(
     source: t.Union[str, int, t.Dict[str, str], Path], **kwargs
 ):
-    """Wrapper to instantiate the appropriate image
+    """
+    Instantiate the image.
 
     Parameters
     ----------
@@ -46,10 +42,9 @@ def instantiate_image(
 
     Examples
     --------
-    image_path = "path/to/image"]
+    image_path = "path/to/image"
     with instantiate_image(image_path) as img:
         print(imz.data, img.metadata)
-
     """
     return dispatch_image(source)(source, **kwargs)
 
@@ -63,14 +58,12 @@ def dispatch_image(source: t.Union[str, int, t.Dict[str, str], Path]):
     elif isinstance(source, dict) or (
         isinstance(source, (str, Path)) and Path(source).is_dir()
     ):
+        # zarr files are considered directories
         if Path(source).suffix == ".zarr":
             instantiator = ImageZarr
         else:
             instantiator = ImageDir
-    elif isinstance(source, Path) and source.is_file():
-        # my addition
-        instantiator = ImageLocalOME
-    elif isinstance(source, str) and Path(source).is_file():
+    elif isinstance(source, (str, Path)) and Path(source).is_file():
         instantiator = ImageLocalOME
     else:
         raise Exception(f"Invalid data source at {source}")
@@ -78,9 +71,7 @@ def dispatch_image(source: t.Union[str, int, t.Dict[str, str], Path]):
 
 
 class BaseLocalImage(ABC):
-    """
-    Base Image class to set path and provide context management method.
-    """
+    """Set path and provide method for context management."""
 
     # default image order
     _default_dimorder = "tczyx"
@@ -112,30 +103,35 @@ class BaseLocalImage(ABC):
         )
         return self._rechunked_img
 
+    @property
+    def data(self):
+        """Get data."""
+        return self.get_data_lazy()
+
+    @property
+    def metadata(self):
+        """Get metadata."""
+        return self._meta
+
+    def set_meta(self):
+        """Load metadata using parser dispatch."""
+        self._meta = dispatch_metadata_parser(self.path)
+
     @abstractmethod
     def get_data_lazy(self) -> da.Array:
+        """Define in child class."""
         pass
 
     @abstractproperty
     def name(self):
+        """Define in child class."""
         pass
 
     @abstractproperty
     def dimorder(self):
+        """Define in child class."""
         pass
 
-    @property
-    def data(self):
-        return self.get_data_lazy()
-
-    @property
-    def metadata(self):
-        return self._meta
-
-    def set_meta(self):
-        """Load metadata using parser dispatch"""
-        self._meta = dispatch_metadata_parser(self.path)
-
 
 class ImageLocalOME(BaseLocalImage):
     """
@@ -146,11 +142,13 @@ class ImageLocalOME(BaseLocalImage):
     """
 
     def __init__(self, path: str, dimorder=None, **kwargs):
+        """Initialise using file name."""
         super().__init__(path)
         self._id = str(path)
         self.set_meta(str(path))
 
     def set_meta(self, path):
+        """Get metadata from the associated tiff file."""
         meta = dict()
         try:
             with TiffFile(path) as f:
@@ -194,7 +192,7 @@ class ImageLocalOME(BaseLocalImage):
 
     @property
     def dimorder(self):
-        """Order of dimensions in image"""
+        """Return order of dimensions in the image."""
         if not hasattr(self, "_dimorder"):
             self._dimorder = self._meta["Image"]["Pixels"]["@DimensionOrder"]
         return self._dimorder
@@ -205,16 +203,16 @@ class ImageLocalOME(BaseLocalImage):
         return self._dimorder
 
     def get_data_lazy(self) -> da.Array:
-        """Return 5D dask array. For lazy-loading  multidimensional tiff files"""
-
+        """Return 5D dask array via lazy-loading of tiff files."""
         if not hasattr(self, "formatted_img"):
-            if not hasattr(self, "ids"):  # Standard dimension order
+            if not hasattr(self, "ids"):
+                # standard order of image dimensions
                 img = (imread(str(self.path))[0],)
-            else:  # Custom dimension order, we rearrange the axes for compatibility
+            else:
+                # bespoke order, so rearrange axes for compatibility
                 img = imread(str(self.path))[0]
                 for i, d in enumerate(self._dimorder):
                     self._meta["size_" + d.lower()] = img.shape[i]
-
                 target_order = (
                     *self.ids,
                     *[
@@ -233,12 +231,13 @@ class ImageLocalOME(BaseLocalImage):
                 img = da.moveaxis(
                     reshaped, range(len(reshaped.shape)), target_order
                 )
-
         return self.rechunk_data(img)
 
 
 class ImageDir(BaseLocalImage):
     """
+    Standard image class for tiff files.
+
     Image class for the case in which all images are split in one or
     multiple folders with time-points and channels as independent files.
     It inherits from BaseLocalImage so we only override methods that are critical.
@@ -247,28 +246,23 @@ class ImageDir(BaseLocalImage):
     - One folder per position.
     - Images are flat.
     - Channel, Time, z-stack and the others are determined by filenames.
-    - Provides Dimorder as it is set in the filenames, or expects order during instatiation
+    - Provides Dimorder as it is set in the filenames, or expects order
     """
 
     def __init__(self, path: t.Union[str, Path], **kwargs):
+        """Initialise using file name."""
         super().__init__(path)
         self.image_id = str(self.path.stem)
-
         self._meta = dir_to_meta(self.path)
 
     def get_data_lazy(self) -> da.Array:
-        """Return 5D dask array. For lazy-loading local multidimensional tiff files"""
-
+        """Return 5D dask array."""
         img = imread(str(self.path / "*.tiff"))
-
         # If extra channels, pick the first stack of the last dimensions
-
         while len(img.shape) > 3:
             img = img[..., 0]
-
         if self._meta:
             self._meta["size_x"], self._meta["size_y"] = img.shape[-2:]
-
             # Reshape using metadata
             # img = da.reshape(img, (*self._meta, *img.shape[1:]))
             img = da.reshape(img, self._meta.values())
@@ -289,6 +283,7 @@ class ImageDir(BaseLocalImage):
 
     @property
     def name(self):
+        """Return name of image directory."""
         return self.path.stem
 
     @property
@@ -302,24 +297,27 @@ class ImageDir(BaseLocalImage):
 class ImageZarr(BaseLocalImage):
     """
     Read zarr compressed files.
-    These are outputed by the script
+
+    These files are generated by the script
     skeletons/scripts/howto_omero/convert_clone_zarr_to_tiff.py
     """
 
     def __init__(self, path: t.Union[str, Path], **kwargs):
+        """Initialise using file name."""
         super().__init__(path)
         self.set_meta()
         try:
             self._img = zarr.open(self.path)
             self.add_size_to_meta()
         except Exception as e:
-            print(f"Could not add size info to metadata: {e}")
+            print(f"ImageZarr: Could not add size info to metadata: {e}.")
 
     def get_data_lazy(self) -> da.Array:
         """Return 5D dask array for lazy-loading local multidimensional zarr files."""
         return self._img
 
     def add_size_to_meta(self):
+        """Add shape of image array to metadata."""
         self._meta.update(
             {
                 f"size_{dim}": shape
@@ -329,16 +327,13 @@ class ImageZarr(BaseLocalImage):
 
     @property
     def name(self):
+        """Return name of zarr directory."""
         return self.path.stem
 
     @property
     def dimorder(self):
-        # FIXME hardcoded order based on zarr compression/cloning script
+        """Impose a hard-coded order of dimensions based on the zarr compression script."""
         return "TCZYX"
-        # Assumes only dimensions start with "size"
-        # return [
-        #     k.split("_")[-1] for k in self._meta.keys() if k.startswith("size")
-        # ]
 
 
 class ImageDummy(BaseLocalImage):
diff --git a/src/aliby/io/omero.py b/src/aliby/io/omero.py
index 0ea37359360598a7335db55081ab9500e91c3efc..8cc4fd939dcf1aacd0ac2e8cb84a48ae87a4f292 100644
--- a/src/aliby/io/omero.py
+++ b/src/aliby/io/omero.py
@@ -253,7 +253,8 @@ class Dataset(BridgeOmero):
         cls,
         filepath: t.Union[str, Path],
     ):
-        """Instatiate Dataset from a hdf5 file.
+        """
+        Instantiate data set from a h5 file.
 
         Parameters
         ----------
diff --git a/src/aliby/tile/tiler.py b/src/aliby/tile/tiler.py
index b0fdbefcce328faefa1425fcaa2886bf38c5d278..b35ca5c10e6611d9eb928c2fc44f2b4b7391e639 100644
--- a/src/aliby/tile/tiler.py
+++ b/src/aliby/tile/tiler.py
@@ -320,7 +320,7 @@ class Tiler(StepABC):
             image.data,
             metadata,
             parameters,
-            tile_locs=tile_locs,
+            tile_locations=tile_locs,
         )
         if hasattr(tile_locs, "drifts"):
             tiler.no_processed = len(tile_locs.drifts)
diff --git a/src/aliby/utils/imageViewer.py b/src/aliby/utils/imageViewer.py
index fd529108dd9091b7ec19041ccc8cf2d265af2fa9..52a15ee763f776aba369276e34748b1becff76c0 100644
--- a/src/aliby/utils/imageViewer.py
+++ b/src/aliby/utils/imageViewer.py
@@ -17,17 +17,22 @@ riv.plot_labelled_trap(tile_id, trange, [0], ncols=ncols)
 
 import re
 import typing as t
+from abc import ABC
 
 import h5py
-from abc import ABC
 import matplotlib.pyplot as plt
 import numpy as np
 import seaborn as sns
-from PIL import Image
 from skimage.morphology import dilation
 
 from agora.io.cells import Cells
 from agora.io.metadata import dispatch_metadata_parser
+from aliby.io.image import ImageDir, ImageZarr, dispatch_image
+
+try:
+    from aliby.io.omero import UnsafeImage as OImage
+except ModuleNotFoundError:
+    print("Viewing available only for local files.")
 from aliby.tile.tiler import Tiler, TilerParameters
 from aliby.utils.plot import stretch_clip
 
@@ -40,9 +45,7 @@ default_colours = {
 
 
 def custom_imshow(a, norm=None, cmap=None, *args, **kwargs):
-    """
-    Wrapper on plt.imshow function.
-    """
+    """Wrap plt.imshow."""
     if cmap is None:
         cmap = "Greys_r"
     return plt.imshow(
@@ -57,16 +60,13 @@ def custom_imshow(a, norm=None, cmap=None, *args, **kwargs):
 
 class BaseImageViewer(ABC):
     def __init__(self, fpath):
-
         self._fpath = fpath
-        attrs = dispatch_metadata_parser(fpath.parent)
+        self.attrs = dispatch_metadata_parser(fpath.parent)
         self._logfiles_meta = {}
-
-        self.image_id = attrs.get("image_id")
+        self.image_id = self.attrs.get("image_id")
         if self.image_id is None:
             with h5py.File(fpath, "r") as f:
                 self.image_id = f.attrs.get("image_id")
-
         assert self.image_id is not None, "No valid image_id found in metadata"
 
     @property
@@ -75,42 +75,39 @@ class BaseImageViewer(ABC):
 
     @property
     def ntraps(self):
+        """Find the number of traps available."""
         return self.cells.ntraps
 
     @property
     def max_labels(self):
-        # Print max cell label in whole experiment
+        """Find maximum cell label in whole experiment."""
         return [max(x) for x in self.cells.labels]
 
     def labels_at_time(self, tp: int):
-        # Print  cell label at a given time-point
+        """Find cell label at a given time point."""
         return self.cells.labels_at_time(tp)
 
 
 class LocalImageViewer(BaseImageViewer):
     """
-    Tool to generate figures from local files, either zarr or files organised
-    in directories.
+    Generate figures from local files.
+
+    File are either zarr or organised in directories.
     TODO move common functionality from RemoteImageViewer to BaseImageViewer
     """
 
-    def __init__(self, results_path: str, data_path: str):
-        super().__init__(results_path)
-
-        from aliby.io.image import ImageDir, ImageZarr
-
+    def __init__(self, h5file_path: str, data_path: str):
+        super().__init__(h5file_path)
         self._image_class = (
-            ImageZarr if data_path.endswith(".zar") else ImageDir
+            ImageZarr if str(data_path).endswith(".zarr") else ImageDir
         )
-
-        with dispatch_image(data_path)(data_path) as image:
-            self.tiler = Tiler(
-                image.data,
-                self._meta if hasattr(self, "_meta") else self._logfiles_meta,
-                TilerParameters.default(),
-            )
-
-        self.cells = Cells.from_source(results_path)
+        image = ImageZarr(data_path)
+        self.tiler = Tiler(
+            image.data,
+            self._meta if hasattr(self, "_meta") else self._logfiles_meta,
+            TilerParameters.default(),
+        )
+        self.cells = Cells.from_source(h5file_path)
 
 
 class RemoteImageViewer(BaseImageViewer):
@@ -126,16 +123,12 @@ class RemoteImageViewer(BaseImageViewer):
         server_info: t.Dict[str, str],
     ):
         super().__init__(results_path)
-
-        from aliby.io.omero import UnsafeImage as OImage
-
         self._server_info = server_info or {
-            k: attrs["parameters"]["general"][k] for k in self._credentials
+            k: self.attrs["parameters"]["general"][k]
+            for k in self._credentials
         }
-
         self._image_instance = OImage(self.image_id, **self._server_info)
         self.tiler = Tiler.from_h5(self._image_instance, results_path)
-
         self.cells = Cells.from_source(results_path)
 
     def random_valid_trap_tp(
@@ -194,7 +187,6 @@ class RemoteImageViewer(BaseImageViewer):
         z: int = None,
         server_info=None,
     ):
-
         if tps and not isinstance(tps, t.Collection):
             tps = range(tps)
 
diff --git a/src/aliby/utils/plot.py b/src/aliby/utils/plot.py
index 3f0a66c0849839fac357851ade037e78e8d17634..8a34c3b7ade6c8abe68e1491d2b0885d815def4a 100644
--- a/src/aliby/utils/plot.py
+++ b/src/aliby/utils/plot.py
@@ -52,7 +52,7 @@ def plot_in_square(data: t.Iterable):
 
 def stretch_clip(image, clip=True):
     """
-    Performs contrast stretching on an input image.
+    Perform contrast stretching on an input image.
 
     This function takes an array-like input image and enhances its contrast by adjusting
     the dynamic range of pixel values. It first scales the pixel values between 0 and 255,