diff --git a/docs/Makefile b/docs/Makefile
index b50c24dc..5117fbf5 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -3,7 +3,7 @@
 
 # You can set these variables from the command line, and also
 # from the environment for the first two.
-SPHINXOPTS    ?= -W
+SPHINXOPTS    ?= -W --keep-going
 SPHINXBUILD   ?= sphinx-build
 SOURCEDIR     = .
 BUILDDIR      = _build
diff --git a/docs/conf.py b/docs/conf.py
index 2c04f853..efff247a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -56,10 +56,18 @@
 automodapi_inheritance_diagram = False
 
 intersphinx_mapping = {
+    "python": ("https://docs.python.org/3/", None),
     "napari": ("https://napari.org/", None),
+    "numpy": ("https://numpy.org/doc/stable/", None),
     "matplotlib": ("https://matplotlib.org/", None),
+    "PyQT6": ("https://www.riverbankcomputing.com/static/Docs/PyQt6/", None),
 }
 
+nitpicky = True
+# Can't work out how to link this properley using intersphinx and the PyQT6 docs.
+# TODO: fix at some point
+nitpick_ignore = [("py:class", "PyQt6.QtWidgets.QWidget")]
+
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ["_templates"]
 
diff --git a/docs/make.bat b/docs/make.bat
index 32bb2452..4b78115a 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -7,6 +7,9 @@ REM Command file for Sphinx documentation
 if "%SPHINXBUILD%" == "" (
 	set SPHINXBUILD=sphinx-build
 )
+if "%SPHINXOPTS%" == "" (
+	set SPHINXOPTS="--keep-going"
+)
 set SOURCEDIR=.
 set BUILDDIR=_build
 
diff --git a/src/napari_matplotlib/base.py b/src/napari_matplotlib/base.py
index b69d0310..fc8fa17f 100644
--- a/src/napari_matplotlib/base.py
+++ b/src/napari_matplotlib/base.py
@@ -22,11 +22,12 @@
 
 class NapariMPLWidget(QWidget):
     """
-    Base Matplotlib canvas. Widget that can be embedded as a napari widget.
+    Widget containing a Matplotlib canvas and toolbar.
 
-    This creates a single FigureCanvas, which contains a single Figure.
-    It is not responsible for creating any Axes, because different widgets
-    may want to implement different subplot layouts.
+    This creates a single FigureCanvas, which contains a single
+    `~matplotlib.figure.Figure`, and an associated toolbar.
+    It is not responsible for creating any Axes, because different
+    widgets may want to implement different subplot layouts.
 
     This class also handles callbacks to automatically update figures when
     the layer selection or z-step is changed in the napari viewer. To take
@@ -60,12 +61,12 @@ def __init__(self, napari_viewer: napari.viewer.Viewer):
         self.layout().addWidget(self.toolbar)
         self.layout().addWidget(self.canvas)
 
-        self.setup_callbacks()
+        self._setup_callbacks()
         self.layers: List[napari.layers.Layer] = []
 
-    # Accept any number of input layers by default
+    #: Number of layers taken as input
     n_layers_input = Interval(None, None)
-    # Accept any type of input layer by default
+    #: Type of layer taken as input
     input_layer_types: Tuple[napari.layers.Layer, ...] = (napari.layers.Layer,)
 
     @property
@@ -83,17 +84,17 @@ def n_selected_layers(self) -> int:
     @property
     def current_z(self) -> int:
         """
-        Current z-step of the viewer.
+        Current z-step of the napari viewer.
         """
         return self.viewer.dims.current_step[0]
 
-    def setup_callbacks(self) -> None:
+    def _setup_callbacks(self) -> None:
         """
         Sets up callbacks.
 
-        Sets up callbacks for:
-        - Layer selection changing
-        - z-step changing
+        Sets up callbacks for when:
+        - Layer selection is changed
+        - z-step is changed
         """
         # z-step changed in viewer
         self.viewer.dims.events.current_step.connect(self._draw)
@@ -102,7 +103,7 @@ def setup_callbacks(self) -> None:
 
     def update_layers(self, event: napari.utils.events.Event) -> None:
         """
-        Update the layers attribute with currently selected layers and re-draw.
+        Update the ``layers`` attribute with currently selected layers and re-draw.
         """
         self.layers = list(self.viewer.layers.selection)
         self._on_update_layers()
@@ -145,7 +146,7 @@ def add_single_axes(self) -> None:
 
     @staticmethod
     def apply_napari_colorscheme(ax: Axes) -> None:
-        """Apply napari-compatible colorscheme to an axes object."""
+        """Apply napari-compatible colorscheme to an Axes."""
         # changing color of axes background to transparent
         ax.set_facecolor("none")
 
diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py
index 405b7b09..858a42a8 100644
--- a/src/napari_matplotlib/scatter.py
+++ b/src/napari_matplotlib/scatter.py
@@ -8,7 +8,7 @@
 from .base import NapariMPLWidget
 from .util import Interval
 
-__all__ = ["ScatterWidget", "FeaturesScatterWidget"]
+__all__ = ["ScatterBaseWidget", "ScatterWidget", "FeaturesScatterWidget"]
 
 
 class ScatterBaseWidget(NapariMPLWidget):
@@ -68,7 +68,7 @@ def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]:
 
 class ScatterWidget(ScatterBaseWidget):
     """
-    Widget to display scatter plot of two similarly shaped image layers.
+    Scatter data in two similarly shaped layers.
 
     If there are more than 500 data points, a 2D histogram is displayed instead
     of a scatter plot, to avoid too many scatter points.
@@ -127,7 +127,7 @@ def __init__(self, napari_viewer: napari.viewer.Viewer):
     @property
     def x_axis_key(self) -> Optional[str]:
         """
-        Key to access x axis data from the FeaturesTable.
+        Key for the x-axis data.
         """
         return self._x_axis_key
 
@@ -139,7 +139,7 @@ def x_axis_key(self, key: Optional[str]) -> None:
     @property
     def y_axis_key(self) -> Optional[str]:
         """
-        Key to access y axis data from the FeaturesTable.
+        Key for the y-axis data.
         """
         return self._y_axis_key
 
diff --git a/src/napari_matplotlib/slice.py b/src/napari_matplotlib/slice.py
index 4e22bad8..c29fff5c 100644
--- a/src/napari_matplotlib/slice.py
+++ b/src/napari_matplotlib/slice.py
@@ -50,7 +50,7 @@ def __init__(self, napari_viewer: napari.viewer.Viewer):
         self.update_layers(None)
 
     @property
-    def layer(self) -> napari.layers.Layer:
+    def _layer(self) -> napari.layers.Layer:
         """
         Layer being plotted.
         """
@@ -73,28 +73,19 @@ def current_dim_index(self) -> int:
         return _dims[::-1].index(self.current_dim)
 
     @property
-    def selector_values(self) -> Dict[str, int]:
+    def _selector_values(self) -> Dict[str, int]:
         """
         Values of the slice selectors.
         """
         return {d: self.slice_selectors[d].value() for d in _dims_sel}
 
-    def update_slice_selectors(self) -> None:
-        """
-        Update range and enabled status of the slice selectors, and the value
-        of the z slice selector.
-        """
-        # Update min/max
-        for i, dim in enumerate(_dims_sel):
-            self.slice_selectors[dim].setRange(0, self.layer.data.shape[i])
-
-    def get_xy(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any]]:
+    def _get_xy(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any]]:
         """
         Get data for plotting.
         """
-        x = np.arange(self.layer.data.shape[self.current_dim_index])
+        x = np.arange(self._layer.data.shape[self.current_dim_index])
 
-        vals = self.selector_values
+        vals = self._selector_values
         vals.update({"z": self.current_z})
 
         slices = []
@@ -109,7 +100,7 @@ def get_xy(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any]]:
 
         # Reverse since z is the first axis in napari
         slices = slices[::-1]
-        y = self.layer.data[tuple(slices)].ravel()
+        y = self._layer.data[tuple(slices)].ravel()
 
         return x, y
 
@@ -123,8 +114,8 @@ def draw(self) -> None:
         """
         Clear axes and draw a 1D plot.
         """
-        x, y = self.get_xy()
+        x, y = self._get_xy()
 
         self.axes.plot(x, y)
         self.axes.set_xlabel(self.current_dim)
-        self.axes.set_title(self.layer.name)
+        self.axes.set_title(self._layer.name)
diff --git a/src/napari_matplotlib/util.py b/src/napari_matplotlib/util.py
index 4ae8ca19..17965caf 100644
--- a/src/napari_matplotlib/util.py
+++ b/src/napari_matplotlib/util.py
@@ -28,6 +28,12 @@ def __init__(self, lower_bound: Optional[int], upper_bound: Optional[int]):
         self.lower = lower_bound
         self.upper = upper_bound
 
+    def __repr__(self) -> str:
+        """
+        Get string representation.
+        """
+        return f"Interval({self.lower}, {self.upper})"
+
     def __contains__(self, val: int) -> bool:
         """
         Return True if val is in the current interval.