diff --git a/doc/images/lightboxtoolbar.png b/doc/images/lightboxtoolbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..13241307998c01d8a195cb99b9eeee145b91fff8
Binary files /dev/null and b/doc/images/lightboxtoolbar.png differ
diff --git a/doc/images/locationpanel.png b/doc/images/locationpanel.png
new file mode 100644
index 0000000000000000000000000000000000000000..a55a2be384f9df50ac8c020e1e1114621210d029
Binary files /dev/null and b/doc/images/locationpanel.png differ
diff --git a/doc/images/orthotoolbar.png b/doc/images/orthotoolbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..3854d22a759ea73347637c01e5c3d1f9ae297f72
Binary files /dev/null and b/doc/images/orthotoolbar.png differ
diff --git a/fsl/fsleyes/controls/lightboxtoolbar.py b/fsl/fsleyes/controls/lightboxtoolbar.py
index 67b6f7b5bb870504715ffb3a345c9642fbd5d3b2..0e4289f6e27637e6327d2765a01c8484a5c5b573 100644
--- a/fsl/fsleyes/controls/lightboxtoolbar.py
+++ b/fsl/fsleyes/controls/lightboxtoolbar.py
@@ -1,9 +1,12 @@
 #!/usr/bin/env python
 #
-# lightboxtoolbar.py -
+# lightboxtoolbar.py - The LightBoxToolBar class.
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
+"""This module provides the :class:`LightBoxToolBar` class, which is a
+:class:`.FSLEyesToolBar` for use with the :class:`.LightBoxPanel`.
+"""
 
 
 import wx
@@ -18,8 +21,30 @@ import fsl.data.strings     as strings
 
 
 class LightBoxToolBar(fsltoolbar.FSLEyesToolBar):
-
+    """The ``LightBoxToolBar`` is a :class:`.FSLEyesToolBar` for use with the
+    :class:`.LightBoxPanel`. A ``LightBoxToolBar`` looks something like this:
+
+    
+    .. image:: images/lightboxtoolbar.png
+       :scale: 50%
+       :align: center
+
+    
+    The ``LightBoxToolBar`` allows the user to control important parts of the
+    :class:`.LightBoxPanel` display, and also to display a
+    :class:`.CanvasSettingsPanel`, which allows control over all aspects of a
+    ``LightBoxPanel``.
+    """
+
+    
     def __init__(self, parent, overlayList, displayCtx, lb):
+        """Create a ``LightBoxToolBar``.
+
+        :arg parent:      The :mod:`wx` parent object.
+        :arg overlayList: The :class:`.OverlayList` instance.
+        :arg displayCtx:  The :class:`.DisplayContext` instance.
+        :arg lb:          The :class:`.LightBoxPanel` instance.
+        """
 
         actionz = {'more' : self.showMoreSettings}
         
@@ -123,6 +148,12 @@ class LightBoxToolBar(fsltoolbar.FSLEyesToolBar):
 
         
     def showMoreSettings(self, *a):
+        """Opens a :class:`.CanvasSettingsPanel` for the
+        :class:`.LightBoxPanel` that owns this ``LightBoxToolBar``.
+
+        The ``CanvasSettingsPanel`` is opened as a floating pane - see the
+        :meth:`.ViewPanel.togglePanel` method.
+        """
         import canvassettingspanel
         self.lightBoxPanel.togglePanel(
             canvassettingspanel.CanvasSettingsPanel,
diff --git a/fsl/fsleyes/controls/locationpanel.py b/fsl/fsleyes/controls/locationpanel.py
index ee9a357dd31e83cc9405076ee9e43dff6c40d23a..d788b5d34c8c151d7ab2200dba99272489fb645f 100644
--- a/fsl/fsleyes/controls/locationpanel.py
+++ b/fsl/fsleyes/controls/locationpanel.py
@@ -4,17 +4,11 @@
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
-"""This module provides the :class:`LocationPanel` class, a panel which
-displays controls allowing the user to change the currently displayed location
-in both world and local coordinates, both in the space of the currently
-selected overlay.
-
-These changes are propagated to the current display coordinate system
-location, managed by the display context (and external changes to the display
-context location are propagated back to the local/world location properties
-managed by a :class:`LocationPanel`).
+"""This module provides the :class:`LocationPanel` class, a *FSLeyes control*
+panel which shows information about the current display location.
 """
 
+
 import logging
 
 import wx
@@ -37,24 +31,69 @@ log = logging.getLogger(__name__)
 
 
 class LocationPanel(fslpanel.FSLEyesPanel):
-    """
-    A wx.Panel which displays information about the current location,
-    for each overlay in the overlay list.
+    """The ``LocationPanel`` is a panel which contains controls allowing the
+    user to view and modify the :attr:`.DisplayContext.location` property. A
+    ``LocationPanel`` is intended to be contained within a
+    :class:`.CanvasPanel`, and looks something like this:
+
+    .. image:: images/locationpanel.png
+       :scale: 50%
+       :align: center
+
+
+    The ``LocationPanel`` contains two main sections:
+    
+      - A collection of controls which show the current
+        :attr:`.DisplayContext.location`
+
+      - A ``wx.html.HtmlWindow`` which displays information about the current
+        :attr:`.DisplayContext.location` for all overlays in the
+        :class:`.OverlayList`.
+
+
+    **NIFTI overlays**
+    
+
+    The ``LocationPanel`` is primarily designed to work with :class:`.Image`
+    overlays. If the :attr:`.DisplayContext.selectedOverlay` is an
+    :class:`.Image`, or has an associated reference image (see the
+    :meth:`.DisplayOpts.getReferenceImage` method), the ``LocationPanel``
+    will display the current :class:`.DisplayContext.location` in both the
+    the voxel coordinates and world coordinates of the ``Image`` instance.
+    
+
+    **Other overlays**
+
+
+    If the :attr:`.DisplayContext.selectedOverlay` is not an :class:`.Image`,
+    or does not have an associated reference image, the ``LocationPanel`` will
+    display the current :attr:`.DisplayContext.location` as-is (i.e. in the
+    display coordinate system); furthermore, the voxel location controls will
+    be disabled.
     """
 
     
     voxelLocation = props.Point(ndims=3, real=False)
-    """If the currently selected overlay is a :class:`.Image`, this property
-    tracks the current display location in voxel coordinates.
+    """If the currently selected overlay is a :class:`.Image` instance , this
+    property tracks the current :attr:`.DisplayContext.location` in voxel
+    coordinates.
     """
     
+    
     worldLocation = props.Point(ndims=3, real=True)
+    """For :class:`.Image` overlays, this property tracks the current
+    :attr:`.DisplayContext.location` in the image world coordinates. For other
+    overlay types, this property tracks the current location in display
+    coordinates.
+    """ 
 
         
     def __init__(self, parent, overlayList, displayCtx):
-        """
-        Creates and lays out the LocationPanel, and sets up a few property
-        event listeners.
+        """Creat a ``LocationPanel``.
+
+        :arg parent:      The :mod:`wx` parent object.
+        :arg overlayList: The :class:`.OverlayList` instance.
+        :arg displayCtx:  The :class:`.DisplayContext` instance.
         """
 
         fslpanel.FSLEyesPanel.__init__(self, parent, overlayList, displayCtx)
@@ -68,7 +107,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         # When the current overlay is either an Image instance, or has
         # an associated reference image, this attributes is used to
         # store a reference to the image.
-        self._refImage = None
+        self.__refImage = None
         
         # When the currently selected overlay is 4D,
         # this attribute will refer to the
@@ -76,27 +115,27 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         # has a volume property that controls the
         # volume - see e.g. the ImageOpts class. This
         # attribute is set in _selectedOverlayChanged.
-        self.volumeTarget = None
+        self.__volumeTarget = None
 
-        self.column1 = wx.Panel(self)
-        self.column2 = wx.Panel(self)
-        self.info    = wxhtml.HtmlWindow(self)
+        self.__column1 = wx.Panel(self)
+        self.__column2 = wx.Panel(self)
+        self.__info    = wxhtml.HtmlWindow(self)
 
         # HTMLWindow does not use
         # the parent font by default,
         # so we force it to at least
         # have the parent font size
-        self.info.SetStandardFonts(self.GetFont().GetPointSize())
+        self.__info.SetStandardFonts(self.GetFont().GetPointSize())
 
-        self.worldLabel  = wx.StaticText(
-            self.column1, label=strings.labels[self, 'worldLocation'])
-        self.volumeLabel = wx.StaticText(
-            self.column1, label=strings.labels[self, 'volume']) 
-        self.voxelLabel  = wx.StaticText(
-            self.column2, label=strings.labels[self, 'voxelLocation'])
+        self.__worldLabel = wx.StaticText(
+            self.__column1, label=strings.labels[self, 'worldLocation'])
+        self.__volumeLabel = wx.StaticText(
+            self.__column1, label=strings.labels[self, 'volume']) 
+        self.__voxelLabel = wx.StaticText(
+            self.__column2, label=strings.labels[self, 'voxelLocation'])
 
         worldX, worldY, worldZ = props.makeListWidgets(
-            self.column1,
+            self.__column1,
             self,
             'worldLocation',
             slider=False,
@@ -105,7 +144,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
             mousewheel=True)
 
         voxelX, voxelY, voxelZ = props.makeListWidgets(
-            self.column2,
+            self.__column2,
             self,
             'voxelLocation',
             slider=False,
@@ -113,69 +152,82 @@ class LocationPanel(fslpanel.FSLEyesPanel):
             showLimits=False,
             mousewheel=True) 
 
-        self.worldX = worldX
-        self.worldY = worldY
-        self.worldZ = worldZ
-        self.voxelX = voxelX
-        self.voxelY = voxelY
-        self.voxelZ = voxelZ
-        self.volume = floatspin.FloatSpinCtrl(
-            self.column2,
+        self.__worldX = worldX
+        self.__worldY = worldY
+        self.__worldZ = worldZ
+        self.__voxelX = voxelX
+        self.__voxelY = voxelY
+        self.__voxelZ = voxelZ
+        self.__volume = floatspin.FloatSpinCtrl(
+            self.__column2,
             style=floatspin.FSC_MOUSEWHEEL | floatspin.FSC_INTEGER)
 
-        self.column1Sizer = wx.BoxSizer(wx.VERTICAL)
-        self.column2Sizer = wx.BoxSizer(wx.VERTICAL)
-        self.sizer        = wx.BoxSizer(wx.HORIZONTAL)
-
-        self.column1Sizer.Add(self.worldLabel,  flag=wx.EXPAND)
-        self.column1Sizer.Add(self.worldX,      flag=wx.EXPAND)
-        self.column1Sizer.Add(self.worldY,      flag=wx.EXPAND)
-        self.column1Sizer.Add(self.worldZ,      flag=wx.EXPAND)
-        self.column1Sizer.Add(self.volumeLabel, flag=wx.ALIGN_RIGHT)
-
-        self.column2Sizer.Add(self.voxelLabel, flag=wx.EXPAND)
-        self.column2Sizer.Add(self.voxelX,     flag=wx.EXPAND)
-        self.column2Sizer.Add(self.voxelY,     flag=wx.EXPAND)
-        self.column2Sizer.Add(self.voxelZ,     flag=wx.EXPAND)
-        self.column2Sizer.Add(self.volume,     flag=wx.EXPAND)
+        self.__column1Sizer = wx.BoxSizer(wx.VERTICAL)
+        self.__column2Sizer = wx.BoxSizer(wx.VERTICAL)
+        self.__sizer        = wx.BoxSizer(wx.HORIZONTAL)
+
+        self.__column1Sizer.Add(self.__worldLabel,  flag=wx.EXPAND)
+        self.__column1Sizer.Add(self.__worldX,      flag=wx.EXPAND)
+        self.__column1Sizer.Add(self.__worldY,      flag=wx.EXPAND)
+        self.__column1Sizer.Add(self.__worldZ,      flag=wx.EXPAND)
+        self.__column1Sizer.Add(self.__volumeLabel, flag=wx.ALIGN_RIGHT)
+
+        self.__column2Sizer.Add(self.__voxelLabel, flag=wx.EXPAND)
+        self.__column2Sizer.Add(self.__voxelX,     flag=wx.EXPAND)
+        self.__column2Sizer.Add(self.__voxelY,     flag=wx.EXPAND)
+        self.__column2Sizer.Add(self.__voxelZ,     flag=wx.EXPAND)
+        self.__column2Sizer.Add(self.__volume,     flag=wx.EXPAND)
         
-        self.sizer.Add(self.column1, flag=wx.EXPAND)
-        self.sizer.Add((5, -1))
-        self.sizer.Add(self.column2, flag=wx.EXPAND)
-        self.sizer.Add((5, -1))
-        self.sizer.Add(self.info,    flag=wx.EXPAND, proportion=1)
-
-        self.column1.SetSizer(self.column1Sizer)
-        self.column2.SetSizer(self.column2Sizer)
-        self        .SetSizer(self.sizer)
+        self.__sizer.Add(self.__column1, flag=wx.EXPAND)
+        self.__sizer.Add((5, -1))
+        self.__sizer.Add(self.__column2, flag=wx.EXPAND)
+        self.__sizer.Add((5, -1))
+        self.__sizer.Add(self.__info,    flag=wx.EXPAND, proportion=1)
+
+        self.__column1.SetSizer(self.__column1Sizer)
+        self.__column2.SetSizer(self.__column2Sizer)
+        self          .SetSizer(self.__sizer)
         
         self._overlayList.addListener('overlays',
                                       self._name,
-                                      self._selectedOverlayChanged)
+                                      self.__selectedOverlayChanged)
         self._displayCtx .addListener('selectedOverlay',
                                       self._name,
-                                      self._selectedOverlayChanged)
+                                      self.__selectedOverlayChanged)
         self._displayCtx .addListener('location',
                                       self._name,
-                                      self._displayLocationChanged)
+                                      self.__displayLocationChanged)
         self.addListener(             'voxelLocation',
                                       self._name,
-                                      self._voxelLocationChanged)
+                                      self.__voxelLocationChanged)
         self.addListener(             'worldLocation',
                                       self._name,
-                                      self._worldLocationChanged)
+                                      self.__worldLocationChanged)
 
-        self._selectedOverlayChanged()
+        self.__selectedOverlayChanged()
 
-        self.worldLabel.SetMinSize(self.__calcWorldLabelMinSize())
-        self.info      .SetMinSize((150, 100))
+        self.__worldLabel.SetMinSize(self.__calcWorldLabelMinSize())
+        self.__info      .SetMinSize((150, 100))
         self.Layout()
-        self.SetMinSize(self.sizer.GetMinSize())
+        self.SetMinSize(self.__sizer.GetMinSize())
+
+
+    def destroy(self):
+        """Must be called when this ``LocationPanel`` is no longer needed.
+        Removes property listeners and calls :meth:`.FSLEyesPanel.destroy`.
+        """
+
+        self._overlayList.removeListener('overlays',        self._name)
+        self._displayCtx .removeListener('selectedOverlay', self._name)
+        self._displayCtx .removeListener('location',        self._name)
+
+        fslpanel.FSLEyesPanel.destroy(self)
 
 
     def __calcWorldLabelMinSize(self):
         """Calculates the minimum size that the world label (the label which
         shows the coordinate space of the currently selected overlay) needs.
+        Called by the :meth:`__init__` method.
         
         The world label displays different things depending on the currently
         selected overlay. But we want it to be a fixed size. So this method
@@ -184,7 +236,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         minimum size for the world label.
         """
 
-        dc = wx.ClientDC(self.worldLabel)
+        dc = wx.ClientDC(self.__worldLabel)
 
         width, height = 0, 0
 
@@ -217,33 +269,24 @@ class LocationPanel(fslpanel.FSLEyesPanel):
 
         return width + 5, height + 5
 
-
-    def destroy(self):
-        """Deregisters property listeners."""
-
-        self._overlayList.removeListener('overlays',        self._name)
-        self._displayCtx .removeListener('selectedOverlay', self._name)
-        self._displayCtx .removeListener('location',        self._name)
-
-        fslpanel.FSLEyesPanel.destroy(self)
-
         
-    def _selectedOverlayChanged(self, *a):
-        """Called when the selected overlay is changed. Updates the voxel label
-        (which contains the overlay name), and sets the voxel location limits.
+    def __selectedOverlayChanged(self, *a):
+        """Called when the :attr:`.DisplayContext.selectedOverlay` or
+        :class:`.OverlayList` is changed. Refreshes the ``LocationPanel``
+        interface accordingly.
         """
 
-        self._updateReferenceImage()
-        self._updateWidgets()
+        self.__updateReferenceImage()
+        self.__updateWidgets()
 
         if len(self._overlayList) == 0:
-            self._updateLocationInfo()
+            self.__updateLocationInfo()
             return
 
         # Register a listener on the DisplayOpts 
         # instance of the currently selected overlay,
         # so we can update the location if the
-        # overlay transforms/reference image change
+        # overlay bounds change.
         overlay = self._displayCtx.getSelectedOverlay()
         for ovl in self._overlayList:
             display = self._displayCtx.getDisplay(ovl)
@@ -252,31 +295,32 @@ class LocationPanel(fslpanel.FSLEyesPanel):
             if ovl is overlay:
                 opts.addListener('bounds',
                                  self._name,
-                                 self._overlayBoundsChanged,
+                                 self.__overlayBoundsChanged,
                                  overwrite=True)
             else:
                 opts.removeListener('bounds', self._name)
 
         # Refresh the world/voxel location properties
-        self._displayLocationChanged()
+        self.__displayLocationChanged()
 
 
-    def _overlayBoundsChanged(self, *a):
+    def __overlayBoundsChanged(self, *a):
+        """Called when the :attr:`.DisplayOpts.bounds` property associated
+        with the currently selected overlay changes. Updates the
+        ``LocationPanel`` interface accordingly.
+        """
 
-        self._updateReferenceImage()
-        self._updateWidgets()
-        self._displayLocationChanged()
+        self.__updateReferenceImage()
+        self.__updateWidgets()
+        self.__displayLocationChanged()
         
 
-    def _updateReferenceImage(self):
-        """Called by the :meth:`_selectedOverlayChanged` and
-        :meth:`_overlayOptsChanged` methods. Looks at the currently selected
-        overlay, and figures out if there is a reference image that can be
-        used to transform between display, world, and voxel coordinate
-        systems.
-
-        Returns ``True`` if the reference image has changed from its
-        previous value, ``False`` otherwise.
+    def __updateReferenceImage(self):
+        """Called by the :meth:`__selectedOverlayChanged` and
+        :meth:`__overlayBoundsChanged` methods. Looks at the currently
+        selected overlay, and figures out if there is a reference image
+        that can be used to transform between display, world, and voxel
+        coordinate systems.
         """
 
         refImage = None
@@ -292,19 +336,24 @@ class LocationPanel(fslpanel.FSLEyesPanel):
             log.debug('Reference image for overlay {}: {}'.format(
                 overlay, refImage))
 
-        self._refImage = refImage
+        self.__refImage = refImage
         
 
-    def _updateWidgets(self):
+    def __updateWidgets(self):
+        """Called by the :meth:`__selectedOverlayChanged` and
+        :meth:`__overlayBoundsChanged` methods.  Enables/disables the
+        voxel/world location and volume controls depending on the currently
+        selected overlay (or reference image).
+        """
 
-        refImage = self._refImage
+        refImage = self.__refImage
 
         haveRef = refImage is not None
 
-        self.voxelX     .Enable(haveRef)
-        self.voxelY     .Enable(haveRef)
-        self.voxelZ     .Enable(haveRef)
-        self.voxelLabel .Enable(haveRef)
+        self.__voxelX     .Enable(haveRef)
+        self.__voxelY     .Enable(haveRef)
+        self.__voxelZ     .Enable(haveRef)
+        self.__voxelLabel .Enable(haveRef)
 
         ######################
         # World location label
@@ -319,7 +368,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
                                              'worldLocation',
                                              'unknown']
 
-        self.worldLabel.SetLabel(label)
+        self.__worldLabel.SetLabel(label)
 
         ####################################
         # Voxel/world location widget limits
@@ -327,10 +376,10 @@ class LocationPanel(fslpanel.FSLEyesPanel):
 
         # Figure out the limits for the
         # voxel/world location widgets
-        if self._refImage is not None:
-            opts     = self._displayCtx.getOpts(self._refImage)
+        if haveRef:
+            opts     = self._displayCtx.getOpts(refImage)
             v2w      = opts.getTransform('voxel', 'world')
-            shape    = self._refImage.shape[:3]
+            shape    = refImage.shape[:3]
             vlo      = [0, 0, 0]
             vhi      = np.array(shape) - 1
             wlo, whi = transform.axisBounds(shape, v2w)
@@ -363,15 +412,15 @@ class LocationPanel(fslpanel.FSLEyesPanel):
 
         # Unbind any listeners between the previous
         # reference image and the volume widget
-        if self.volumeTarget is not None:
-            props.unbindWidget(self.volume,
-                               self.volumeTarget,
+        if self.__volumeTarget is not None:
+            props.unbindWidget(self.__volume,
+                               self.__volumeTarget,
                                'volume',
                                floatspin.EVT_FLOATSPIN)
             
-            self.volumeTarget = None
-            self.volume.SetValue(0)
-            self.volume.SetRange(0, 0)
+            self.__volumeTarget = None
+            self.__volume.SetValue(0)
+            self.__volume.SetRange(0, 0)
 
         # Enable/disable the volume widget if the
         # overlay is a 4D image, and bind/unbind
@@ -379,22 +428,86 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         # the associated ImageOpts instance
         if haveRef and refImage.is4DImage():
             opts = self._displayCtx.getOpts(refImage)
-            self.volumeTarget = opts
+            self.__volumeTarget = opts
 
             props.bindWidget(
-                self.volume, opts, 'volume', floatspin.EVT_FLOATSPIN)
+                self.__volume, opts, 'volume', floatspin.EVT_FLOATSPIN)
 
-            self.volume.SetRange(0, refImage.shape[3] - 1)
-            self.volume.SetValue(opts.volume)
+            self.__volume.SetRange(0, refImage.shape[3] - 1)
+            self.__volume.SetValue(opts.volume)
 
-            self.volume     .Enable()
-            self.volumeLabel.Enable()
+            self.__volume     .Enable()
+            self.__volumeLabel.Enable()
         else:
-            self.volume     .Disable()
-            self.volumeLabel.Disable() 
+            self.__volume     .Disable()
+            self.__volumeLabel.Disable() 
 
             
-    def _prePropagate(self):
+    def __displayLocationChanged(self, *a):
+        """Called when the :attr:`.DisplayContext.location` changes.
+        Propagates the change on to the :attr:`voxelLocation`
+        and :attr:`worldLocation` properties.
+
+        .. note:: Because the :attr:`.DisplayContext.location`,
+                  :attr:`voxelLocation` and :attr:`worldLocation` properties
+                  are all linked through property listeners (see
+                  :meth:`props.HasProperties.addListener`), we need to be a
+                  bit careful to avoid circular updates. Therefore, each of
+                  the :meth:`__displayLocationChanged`,
+                  :meth:`__worldLocationChanged` and
+                  :meth:`__voxelLocationChanged` methods use the
+                  :meth:`__prePropagate`, :meth:`__propagate`, and
+                  :meth:`__postPropagate` methods to propagate changes
+                  between the three location properties.
+        """
+
+        if len(self._overlayList) == 0: return
+
+        self.__prePropagate()
+        self.__propagate('display', 'voxel')
+        self.__propagate('display', 'world')
+        self.__postPropagate()
+        self.__updateLocationInfo()
+
+
+    def __worldLocationChanged(self, *a):
+        """Called when the :attr:`worldLocation` changes.  Propagates the
+        change on to the :attr:`voxelLocation` and
+        :attr:`.DisplayContext.location` properties.
+        """
+        
+        if len(self._overlayList) == 0: return
+
+        self.__prePropagate()
+        self.__propagate('world', 'voxel')
+        self.__propagate('world', 'display')
+        self.__postPropagate()
+        self.__updateLocationInfo()
+
+        
+    def __voxelLocationChanged(self, *a):
+        """Called when the :attr:`voxelLocation` changes.  Propagates the
+        change on to the :attr:`worldLocation` and
+        :attr:`.DisplayContext.location` properties.
+        """ 
+        
+        if len(self._overlayList) == 0: return
+
+        self.__prePropagate()
+        self.__propagate('voxel', 'world')
+        self.__propagate('voxel', 'display')
+        self.__postPropagate()
+        self.__updateLocationInfo()
+
+            
+    def __prePropagate(self):
+        """Called by the :meth:`__displayLocationChanged`,
+        :meth:`__worldLocationChanged` and :meth:`__voxelLocationChanged`
+        methods.
+
+        Disables notification of all location property listeners, so
+        circular updates do not occur.
+        """
 
         self            .disableNotification('voxelLocation')
         self            .disableNotification('worldLocation')
@@ -403,14 +516,26 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         self.Freeze()
 
         
-    def _propagate(self, source, target):
+    def __propagate(self, source, target):
+        """Called by the :meth:`__displayLocationChanged`,
+        :meth:`__worldLocationChanged` and :meth:`__voxelLocationChanged`
+        methods. Copies the coordinates from the ``source`` location to the
+        ``target`` location. Valid values for the ``source`` and ``target``
+        are:
+
+        =========== ==============================================
+        ``display`` The :attr:`.DisplayContext.location` property.
+        ``voxel``   The :attr:`voxelLocation` property.
+        ``world``   The :attr:`worldLocation` property.
+        =========== ==============================================
+        """ 
 
         if   source == 'display': coords = self._displayCtx.location.xyz
         elif source == 'voxel':   coords = self.voxelLocation.xyz
         elif source == 'world':   coords = self.worldLocation.xyz
 
-        if self._refImage is not None:
-            opts    = self._displayCtx.getOpts(self._refImage)
+        if self.__refImage is not None:
+            opts    = self._displayCtx.getOpts(self.__refImage)
             xformed = opts.transformCoords([coords], source, target)[0]
         else:
             xformed = coords
@@ -423,7 +548,14 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         elif target == 'world':   self.worldLocation.xyz = xformed
         
     
-    def _postPropagate(self):
+    def __postPropagate(self):
+        """Called by the :meth:`__displayLocationChanged`,
+        :meth:`__worldLocationChanged` and :meth:`__voxelLocationChanged`
+        methods.
+
+        Re-enables the property listeners that were disabled by the
+        :meth:`__postPropagate` method.
+        """ 
         self            .enableNotification('voxelLocation')
         self            .enableNotification('worldLocation')
         self._displayCtx.enableListener(    'location', self._name)
@@ -432,48 +564,15 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         self.Refresh()
         self.Update()
 
-    
-    def _displayLocationChanged(self, *a):
-        """Called when the :attr:`.DisplayContext.location` changes.
-        Propagates the change on to the :attr:`voxelLocation`
-        and :attr:`worldLocation` properties.
-        """
-
-        if len(self._overlayList) == 0: return
-
-        self._prePropagate()
-        self._propagate('display', 'voxel')
-        self._propagate('display', 'world')
-        self._postPropagate()
-        self._updateLocationInfo()
-
-
-    def _worldLocationChanged(self, *a):
-        
-        if len(self._overlayList) == 0: return
-
-        self._prePropagate()
-        self._propagate('world', 'voxel')
-        self._propagate('world', 'display')
-        self._postPropagate()
-        self._updateLocationInfo()
-
-        
-    def _voxelLocationChanged(self, *a):
-        
-        if len(self._overlayList) == 0: return
-
-        self._prePropagate()
-        self._propagate('voxel', 'world')
-        self._propagate('voxel', 'display')
-        self._postPropagate()
-        self._updateLocationInfo()
 
-
-    def _updateLocationInfo(self):
+    def __updateLocationInfo(self):
+        """Called whenever the :attr:`.DisplayContext.location` changes.
+        Updates the HTML panel which displays information about all overlays
+        in the :class:`.OverlayList`.
+        """
 
         if len(self._overlayList) == 0:
-            self.info.SetPage('')
+            self.__info.SetPage('')
             return
 
         overlays = self._displayCtx.getOrderedOverlays()
@@ -520,5 +619,5 @@ class LocationPanel(fslpanel.FSLEyesPanel):
             if info is not None:
                 lines.append(info)
                 
-        self.info.SetPage('<br>'.join(lines))
-        self.info.Refresh()
+        self.__info.SetPage('<br>'.join(lines))
+        self.__info.Refresh()
diff --git a/fsl/fsleyes/controls/orthotoolbar.py b/fsl/fsleyes/controls/orthotoolbar.py
index 7e5655dc84d2df1a720fb52748590892937b99d6..8ad584f39a032f7b5fd7c1b9913a0237314b95f3 100644
--- a/fsl/fsleyes/controls/orthotoolbar.py
+++ b/fsl/fsleyes/controls/orthotoolbar.py
@@ -1,9 +1,12 @@
 #!/usr/bin/env python
 #
-# orthotoolbar.py -
+# orthotoolbar.py - The OrthoToolBar class.
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
+"""This module provides the :class:`OrthoToolBar` class, which is a
+:class:`.FSLEyesToolBar` for use with the :class:`.OrthoPanel`.
+"""
 
 
 import props
@@ -16,9 +19,40 @@ import fsl.data.strings     as strings
 
 
 class OrthoToolBar(fsltoolbar.FSLEyesToolBar):
+    """The ``OrthoToolBar`` is a :class:`.FSLEyesToolBar` for use with the
+    :class:`.OrthoPanel`. An ``OrthoToolBar`` looks something like this:
+
+    
+    .. image:: images/orthotoolbar.png
+       :scale: 50%
+       :align: center
+
+    
+    The ``OrthoToolBar`` allows the user to control important parts of the
+    :class:`.OrthoPanel` display, and also to display a
+    :class:`.CanvasSettingsPanel`, which allows control over all aspects of
+    an ``OrthoPanel``.
+
+    The ``OrthoToolBar`` contains controls which modify properties, or run
+    actions, defined on the following classes:
+
+    .. autosummary::
+       :nosignatures:
+
+       ~fsl.fsleyes.views.orthopanel.OrthoPanel
+       ~fsl.fsleyes.displaycontext.orthoopts.OrthoOpts
+       ~fsl.fsleyes.profiles.orthoviewprofile.OrthoViewProfile
+    """
 
     
     def __init__(self, parent, overlayList, displayCtx, ortho):
+        """Create an ``OrthoToolBar``.
+
+        :arg parent:      The :mod:`wx` parent object.
+        :arg overlayList: The :class:`.OverlayList` instance.
+        :arg displayCtx:  The :class:`.DisplayContext` instance.
+        :arg ortho:       The :class:`.OrthoPanel` instance.
+        """ 
 
         actionz = {'more' : self.showMoreSettings}
         
@@ -39,6 +73,11 @@ class OrthoToolBar(fsltoolbar.FSLEyesToolBar):
 
 
     def __makeTools(self, *a):
+        """Called by :meth:`__init__`, and whenever the
+        :attr:`.ViewPanel.profile` property changes.
+
+        Re-creates all tools shown on this ``OrthoToolBar``.
+        """
         
         ortho     = self.orthoPanel
         orthoOpts = ortho.getSceneOptions()
@@ -139,6 +178,13 @@ class OrthoToolBar(fsltoolbar.FSLEyesToolBar):
 
     
     def showMoreSettings(self, *a):
+        """Opens a :class:`.CanvasSettingsPanel` for the
+        :class:`.OrthoPanel` that owns this ``OrthoToolBar``.
+
+        The ``CanvasSettingsPanel`` is opened as a floating pane - see the
+        :meth:`.ViewPanel.togglePanel` method.
+        """
+        
         import canvassettingspanel
         self.orthoPanel.togglePanel(canvassettingspanel.CanvasSettingsPanel,
                                     self.orthoPanel,