diff --git a/fsl/fsleyes/views/canvaspanel.py b/fsl/fsleyes/views/canvaspanel.py
index 6e95555ef665d4d8015325f7b61c49493826ae47..9ac670741d461a93f757d4dc6976dd1c3e393937 100644
--- a/fsl/fsleyes/views/canvaspanel.py
+++ b/fsl/fsleyes/views/canvaspanel.py
@@ -36,8 +36,8 @@ import fsl.fsleyes.controls.clusterpanel          as clusterpanel
 import fsl.fsleyes.controls.lookuptablepanel      as lookuptablepanel
 import fsl.fsleyes.controls.shellpanel            as shellpanel
 
-import                                  colourbarpanel
-import                                  viewpanel
+import                                               colourbarpanel
+import                                               viewpanel
 
 
 log = logging.getLogger(__name__)
@@ -64,10 +64,16 @@ class CanvasPanel(viewpanel.ViewPanel):
     Sub-classes of the ``CanvasPanel`` must do the following:
     
       1. Add their content to the panel that is accessible via the
-         :meth:`getCanvasPanel` method (see the note on
+         :meth:`getContentPanel` method (see the note on
          :ref:`adding content <canvaspanel-adding-content>`).
     
       2. Override the :meth:`getGLCanvases` method.
+
+      3. Call the :meth:`centrePanelLayout` method in their ``__init__``
+         method.
+
+      4. Override the :meth:`centrePanelLayout` method if any custom layout is
+         necessary.
     
     
     **Actions**
@@ -104,14 +110,14 @@ class CanvasPanel(viewpanel.ViewPanel):
 
 
     .. _canvaspanel-adding-content:
+
     
     **Adding content**
 
     
-    To support colour bar functionality, the ``CanvasPanel`` uses a hierarchy
-    of ``wx.Panel`` instances, depicted in the following containment
-    hierarchy diagram:
-
+    To support colour bar and screenshot functionality, the ``CanvasPanel``
+    uses a hierarchy of ``wx.Panel`` instances, depicted in the following
+    containment hierarchy diagram:
     
     .. graphviz::
 
@@ -127,23 +133,49 @@ class CanvasPanel(viewpanel.ViewPanel):
          rankdir="BT";
     
          1 [label="CanvasPanel"];
-         2 [label="Canvas container"];
-         3 [label="ColourBarPanel"];
-         4 [label="Centre panel"];
-         5 [label="Content added by sub-classes"];
+         2 [label="Centre panel"];
+         3 [label="Advanced layout"];
+         4 [label="Container panel"];
+         5 [label="ColourBarPanel"];
+         6 [label="Content panel"];
+         7 [label="Content added by sub-classes"];
 
          2 -> 1;
          3 -> 2;
          4 -> 2;
          5 -> 4;
+         6 -> 4;
+         7 -> 6;
        }
 
     
     As depicted in the diagram, sub-classes need to add their content to the
-    *centre panel*. This panel is accessible via the :meth:`getCanvasPanel`
-    method. The *container panel* is what gets passed to the
+    *content panel*. This panel is accessible via the :meth:`getContentPanel`
+    method. 
+
+    
+    The *centre panel* is what gets passed to the
     :meth:`.ViewPanel.setCentrePanel` method, and is accessible via the
-    :meth:`getCanvasContainer` method, if necessary.
+    :meth:`getCentrePanel` method, if necessary. The *container panel* is
+    also available, via the :meth:`getContainerPanel`. Everything in the
+    container panel will appear in screenshots (see the :meth:`screenshot`
+    method).
+
+    
+    The :meth:`centrePanelLayout` method lays out the centre panel, using the
+    :meth:`layoutContainerPanel` method to lay out the colour bar and the
+    content panel. The ``centrePanelLayout`` method simply adds the canvas
+    container directly to the centre panel. Sub-classes which have more
+    advanced layout requirements (e.g.  the :class:`.LightBoxPanel` needs a
+    scrollbar) may override the :meth:`centrePanelLayout` method to implement
+    their own layout.  These sub-class implementations must:
+
+      1. Call the :meth:`layoutCanvasContainer` method.
+
+      2. Add the container panel (accessed via :meth:`getContainerPanel`)
+         to the centre panel (:meth:`getCentrePanel`)
+
+      3. Add any other custom content to the centre panel.
     """
 
     
@@ -274,10 +306,11 @@ class CanvasPanel(viewpanel.ViewPanel):
             self.disableProperty('syncOverlayOrder')
             self.disableProperty('syncOverlayDisplay')
 
-        self.__canvasContainer = wx.Panel(self)
-        self.__canvasPanel     = wx.Panel(self.__canvasContainer)
+        self.__centrePanel    = wx.Panel(self)
+        self.__containerPanel = wx.Panel(self.__centrePanel)
+        self.__contentPanel   = wx.Panel(self.__containerPanel)
 
-        self.setCentrePanel(self.__canvasContainer)
+        self.setCentrePanel(self.__centrePanel)
 
         # Stores a reference to a wx.Timer
         # when movie mode is enabled
@@ -291,17 +324,18 @@ class CanvasPanel(viewpanel.ViewPanel):
                          self.__movieRateChanged)
 
         # Canvas/colour bar layout is managed in
-        # the _layout/_toggleColourBar methods
-        self.__canvasSizer   = None
-        self.__colourBar     = None
+        # the layoutColourBarAndCanvas method
+        self.__colourBar = None
 
         # Use a different listener name so that subclasses
         # can register on the same properties with self._name
         lName = 'CanvasPanel_{}'.format(self._name)
-        self.__opts.addListener('colourBarLocation', lName, self.__layout)
-        self.__opts.addListener('showColourBar',     lName, self.__layout)
-        
-        self.__layout()
+        self.__opts.addListener('colourBarLocation',
+                                lName,
+                                self.__colourBarPropsChanged)
+        self.__opts.addListener('showColourBar',
+                                lName,
+                                self.__colourBarPropsChanged)
 
 
     def destroy(self):
@@ -337,20 +371,28 @@ class CanvasPanel(viewpanel.ViewPanel):
         return self.__opts
                 
         
-    def getCanvasPanel(self):
+    def getCentrePanel(self):
+        """Returns the ``wx.Panel`` which is passed to
+        :meth:`.ViewPanel.setCentrePanel`. See the note on
+        :ref:`adding content <canvaspanel-adding-content>`.
+        """
+        return self.__centrePanel
+
+    
+    def getContentPanel(self):
         """Returns the ``wx.Panel`` to which sub-classes must add their content.
         See the note on :ref:`adding content <canvaspanel-adding-content>`.
         """
-        return self.__canvasPanel
+        return self.__contentPanel 
 
 
-    def getCanvasContainer(self):
+    def getContainerPanel(self):
         """Returns the ``wx.Panel`` which contains the
-        :class:`.ColourBarPanel` if it is being displayed, and the canvas
+        :class:`.ColourBarPanel` if it is being displayed, and the content
         panel. See the note on
         :ref:`adding content <canvaspanel-adding-content>`.
         """
-        return self.__canvasContainer
+        return self.__containerPanel
 
 
     def getGLCanvases(self):
@@ -375,11 +417,27 @@ class CanvasPanel(viewpanel.ViewPanel):
         return None
 
 
-    def __layout(self, *a):
-        """Called when any colour bar display properties are changed (see
-        :class:`.SceneOpts`). Lays out the container panel, which contains
-        the :class:`.ColourBarPanel` and all content added by the
-        ``CanvasPanel`` sub-class implementation.
+    def centrePanelLayout(self):
+        """Lays out the centre panel. This method may be overridden by
+        sub-classes which need more advanced layout logic. See the note on
+        :ref:`adding content <canvaspanel-adding-content>`
+        """
+
+        self.layoutContainerPanel()
+
+        sizer = wx.BoxSizer(wx.HORIZONTAL)
+        sizer.Add(self.__containerPanel, flag=wx.EXPAND, proportion=1)
+        self.__centrePanel.SetSizer(sizer)
+        
+        self.PostSizeEvent()
+        
+    
+    def layoutContainerPanel(self):
+        """Creates a ``wx.Sizer``, and uses it to lay out the colour bar panel
+        and canvas panel. The sizer object is returned.
+
+        This method is used by the default :meth:`centrePanelLayout` method,
+        and is available for custom sub-class implementations to use.
         """
 
         if not self.__opts.showColourBar:
@@ -391,19 +449,15 @@ class CanvasPanel(viewpanel.ViewPanel):
                 self.__colourBar.destroy()
                 self.__colourBar.Destroy()
                 self.__colourBar = None
-                
-            self.__canvasSizer = wx.BoxSizer(wx.HORIZONTAL)
-            self.__canvasSizer.Add(self.__canvasPanel,
-                                   flag=wx.EXPAND,
-                                   proportion=1)
 
-            self.__canvasContainer.SetSizer(self.__canvasSizer)
-            self.PostSizeEvent()
+            sizer = wx.BoxSizer(wx.HORIZONTAL)
+            sizer.Add(self.__contentPanel, flag=wx.EXPAND, proportion=1)
+            self.__containerPanel.SetSizer(sizer)
             return
 
         if self.__colourBar is None:
             self.__colourBar = colourbarpanel.ColourBarPanel(
-                self.__canvasContainer, self._overlayList, self._displayCtx)
+                self.__containerPanel, self._overlayList, self._displayCtx)
 
         self.__opts.bindProps('colourBarLabelSide',
                               self.__colourBar,
@@ -415,23 +469,18 @@ class CanvasPanel(viewpanel.ViewPanel):
             self.__colourBar.orientation = 'vertical'
         
         if self.__opts.colourBarLocation in ('top', 'bottom'):
-            self.__canvasSizer = wx.BoxSizer(wx.VERTICAL)
+            sizer = wx.BoxSizer(wx.VERTICAL)
         else:
-            self.__canvasSizer = wx.BoxSizer(wx.HORIZONTAL)
-
-        self.__canvasContainer.SetSizer(self.__canvasSizer)
+            sizer = wx.BoxSizer(wx.HORIZONTAL)
 
         if self.__opts.colourBarLocation in ('top', 'left'):
-            self.__canvasSizer.Add(self.__colourBar,   flag=wx.EXPAND)
-            self.__canvasSizer.Add(self.__canvasPanel, flag=wx.EXPAND,
-                                   proportion=1)
+            sizer.Add(self.__colourBar,    flag=wx.EXPAND)
+            sizer.Add(self.__contentPanel, flag=wx.EXPAND, proportion=1)
         else:
-            self.__canvasSizer.Add(self.__canvasPanel, flag=wx.EXPAND,
-                                   proportion=1)
-            self.__canvasSizer.Add(self.__colourBar,   flag=wx.EXPAND)
+            sizer.Add(self.__contentPanel, flag=wx.EXPAND, proportion=1)
+            sizer.Add(self.__colourBar,    flag=wx.EXPAND)
 
-        # Force the canvas panel to resize itself
-        self.PostSizeEvent()
+        self.__containerPanel.SetSizer(sizer)
 
 
     def __movieModeChanged(self, *a):
@@ -455,6 +504,13 @@ class CanvasPanel(viewpanel.ViewPanel):
         self.__movieTimer = wx.Timer(self)
         self.Bind(wx.EVT_TIMER, self.__movieUpdate)
         self.__movieTimer.Start(rate)
+
+
+    def __colourBarPropsChanged(self, *a):
+        """Called when any colour bar display properties are changed (see
+        :class:`.SceneOpts`). Calls :meth:`canvasPanelLayout`.
+        """
+        self.centrePanelLayout()
         
 
     def __movieRateChanged(self, *a):
@@ -653,7 +709,7 @@ def _screenshot(overlayList, displayCtx, canvasPanel):
         # direct parent of the colour bar
         # canvas, and an ancestor of the
         # other GL canvases
-        parent        = canvasPanel.getCanvasContainer()
+        parent        = canvasPanel.getContainerPanel()
         width, height = parent.GetClientSize().Get()
         windowDC      = wx.WindowDC(parent)
         memoryDC      = wx.MemoryDC()
diff --git a/fsl/fsleyes/views/lightboxpanel.py b/fsl/fsleyes/views/lightboxpanel.py
index 0d3de04f3e24cb7b70e36179650bff1d5b8d9e2e..7ac448133b5a65dfbbb221ac93bab5c4ddb434fb 100644
--- a/fsl/fsleyes/views/lightboxpanel.py
+++ b/fsl/fsleyes/views/lightboxpanel.py
@@ -86,11 +86,11 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
                                          actionz)
 
         self.__scrollbar = wx.ScrollBar(
-            self.getCanvasPanel(),
+            self.getCentrePanel(),
             style=wx.SB_VERTICAL)
         
         self.__lbCanvas  = lightboxcanvas.WXGLLightBoxCanvas(
-            self.getCanvasPanel(),
+            self.getContentPanel(),
             overlayList,
             displayCtx)
 
@@ -117,10 +117,9 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
         sceneOpts.bindProps('zrange',       self.__lbCanvas)
 
         self.__canvasSizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.getCanvasPanel().SetSizer(self.__canvasSizer)
+        self.getContentPanel().SetSizer(self.__canvasSizer)
 
-        self.__canvasSizer.Add(self.__lbCanvas,  flag=wx.EXPAND, proportion=1)
-        self.__canvasSizer.Add(self.__scrollbar, flag=wx.EXPAND)
+        self.__canvasSizer.Add(self.__lbCanvas, flag=wx.EXPAND, proportion=1)
 
         # When the display context location changes,
         # make sure the location is shown on the canvas
@@ -162,8 +161,9 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
 
         self.__onLightBoxChange()
         self.__onZoom()
+        
         self.__selectedOverlayChanged()
-        self.Layout()
+        self.centrePanelLayout()
         self.initProfile()
 
         # The ViewPanel AuiManager seems to
@@ -204,6 +204,25 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
         """Returns a reference to the :class:`.LightBoxCanvas` instance. """
         return self.__lbCanvas
 
+    
+    def centrePanelLayout(self):
+        """Overrides :meth:`.CanvasPanel.centrePanelLayout`. Adds the
+        scrollbar to the centre panel.
+        """
+
+        self.layoutContainerPanel()
+        
+        centrePanel    = self.getCentrePanel()
+        containerPanel = self.getContainerPanel()
+        sizer          = wx.BoxSizer(wx.HORIZONTAL)
+
+        centrePanel.SetSizer(sizer)
+
+        sizer.Add(containerPanel,   flag=wx.EXPAND, proportion=1)
+        sizer.Add(self.__scrollbar, flag=wx.EXPAND)
+
+        self.PostSizeEvent()
+
         
     def __selectedOverlayChanged(self, *a):
         """Called when the :attr:`.DisplayContext.selectedOverlay` changes.
diff --git a/fsl/fsleyes/views/orthopanel.py b/fsl/fsleyes/views/orthopanel.py
index 5ae778dac51596a86598ae20ea6aa8ac5f54b167..96e2f20ce8fe4a42bbdf79fcb79e040a3c04e94f 100644
--- a/fsl/fsleyes/views/orthopanel.py
+++ b/fsl/fsleyes/views/orthopanel.py
@@ -148,19 +148,19 @@ class OrthoPanel(canvaspanel.CanvasPanel):
                                          sceneOpts,
                                          actionz)
 
-        canvasPanel = self.getCanvasPanel()
+        contentPanel = self.getContentPanel()
 
         # The canvases themselves - each one displays a
         # slice along each of the three world axes
-        self.__xcanvas = slicecanvas.WXGLSliceCanvas(canvasPanel,
+        self.__xcanvas = slicecanvas.WXGLSliceCanvas(contentPanel,
                                                      overlayList,
                                                      displayCtx,
                                                      zax=0)
-        self.__ycanvas = slicecanvas.WXGLSliceCanvas(canvasPanel,
+        self.__ycanvas = slicecanvas.WXGLSliceCanvas(contentPanel,
                                                      overlayList,
                                                      displayCtx,
                                                      zax=1)
-        self.__zcanvas = slicecanvas.WXGLSliceCanvas(canvasPanel,
+        self.__zcanvas = slicecanvas.WXGLSliceCanvas(contentPanel,
                                                      overlayList,
                                                      displayCtx,
                                                      zax=2)
@@ -172,9 +172,9 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         self.__zLabels = {}
         
         for side in ('left', 'right', 'top', 'bottom'):
-            self.__xLabels[side] = wx.StaticText(canvasPanel)
-            self.__yLabels[side] = wx.StaticText(canvasPanel)
-            self.__zLabels[side] = wx.StaticText(canvasPanel)
+            self.__xLabels[side] = wx.StaticText(contentPanel)
+            self.__yLabels[side] = wx.StaticText(contentPanel)
+            self.__zLabels[side] = wx.StaticText(contentPanel)
 
         self.__xcanvas.bindProps('showCursor',   sceneOpts)
         self.__ycanvas.bindProps('showCursor',   sceneOpts)
@@ -236,13 +236,14 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         # the slice canvases when the canvas
         # panel is resized, so aspect ratio
         # is maintained
-        canvasPanel.Bind(wx.EVT_SIZE, self.__onResize)
+        contentPanel.Bind(wx.EVT_SIZE, self.__onResize)
 
         # Initialise the panel
         self.__refreshLayout()
         self.__bgColourChanged()
         self.__overlayListChanged()
         self.__locationChanged()
+        self.centrePanelLayout()
         self.initProfile()
 
         # The ViewPanel AuiManager seems to
@@ -328,8 +329,8 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         bg = [int(round(c * 255)) for c in bg]
         fg = [int(round(c * 255)) for c in fg]
 
-        self.getCanvasPanel().SetBackgroundColour(bg)
-        self.getCanvasPanel().SetForegroundColour(fg)
+        self.getContentPanel().SetBackgroundColour(bg)
+        self.getContentPanel().SetForegroundColour(fg)
 
         self.__xcanvas.SetBackgroundColour(bg)
         self.__ycanvas.SetBackgroundColour(bg)
@@ -539,7 +540,7 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         opts   = self.getSceneOptions()
         layout = opts.layout
 
-        width, height = self.getCanvasPanel().GetClientSize().Get()
+        width, height = self.getContentPanel().GetClientSize().Get()
 
         show     = [opts.showXCanvas,  opts.showYCanvas,  opts.showZCanvas]
         canvases = [self.__xcanvas,    self.__ycanvas,    self.__zcanvas]
@@ -765,7 +766,7 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         for w in widgets:
             self.__canvasSizer.Add(w, flag=flag)
                                           
-        self.getCanvasPanel().SetSizer(self.__canvasSizer)
+        self.getContentPanel().SetSizer(self.__canvasSizer)
 
         # Calculate/ adjust the appropriate sizes
         # for each canvas, such that they are scaled
@@ -775,7 +776,7 @@ class OrthoPanel(canvaspanel.CanvasPanel):
         self.__calcCanvasSizes()
 
         self.Layout()
-        self.getCanvasPanel().Layout()
+        self.getContentPanel().Layout()
         self.Refresh()