diff --git a/fsl/fsleyes/gl/annotations.py b/fsl/fsleyes/gl/annotations.py
index 06b9a42b820fbcc75832b3751f86d8b8c858b5f9..e73348e827acb1be0bf7bd7a78bf9d94ed007c2b 100644
--- a/fsl/fsleyes/gl/annotations.py
+++ b/fsl/fsleyes/gl/annotations.py
@@ -95,21 +95,27 @@ class Annotations(object):
     def line(self, *args, **kwargs):
         """Queues a line for drawing - see the :class:`Line` class. """
         hold = kwargs.pop('hold', False)
-        return self.obj(Line(*args, **kwargs), hold)
+        obj  = Line(self.__xax, self.__yax, *args, **kwargs)
+        
+        return self.obj(obj, hold)
 
         
     def rect(self, *args, **kwargs):
         """Queues a rectangle for drawing - see the :class:`Rectangle` class.
         """
         hold = kwargs.pop('hold', False)
-        return self.obj(Rect(*args, **kwargs), hold)
+        obj  = Rect(self.__xax, self.__yax, *args, **kwargs)
+        
+        return self.obj(obj, hold)
 
 
     def grid(self, *args, **kwargs):
         """Queues a voxel grid for drawing - see the :class:`VoxelGrid` class.
         """ 
         hold = kwargs.pop('hold', False)
-        return self.obj(VoxelGrid(*args, **kwargs), hold)
+        obj  = VoxelGrid(self.__xax, self.__yax, *args, **kwargs)
+        
+        return self.obj(obj, hold)
 
     
     def selection(self, *args, **kwargs):
@@ -117,7 +123,9 @@ class Annotations(object):
         class.
         """ 
         hold = kwargs.pop('hold', False)
-        return self.obj(VoxelSelection(*args, **kwargs), hold) 
+        obj  = VoxelSelection(self.__xax, self.__yax, *args, **kwargs)
+        
+        return self.obj(obj, hold) 
     
         
     def obj(self, obj, hold=False):
@@ -236,9 +244,13 @@ class AnnotationObject(globject.GLSimpleObject):
     :meth:`globject.GLObject.draw` method.
     """
     
-    def __init__(self, xform=None, colour=None, width=None):
+    def __init__(self, xax, yax, xform=None, colour=None, width=None):
         """Create an ``AnnotationObject``.
 
+        :arg xax:    Initial display X axis
+
+        :arg yax:    Initial display Y axis        
+
         :arg xform:  Transformation matrix which will be applied to all
                      vertex coordinates.
         
@@ -246,7 +258,7 @@ class AnnotationObject(globject.GLSimpleObject):
         
         :arg width:  Line width to use for the annotation.
         """
-        globject.GLSimpleObject.__init__(self)
+        globject.GLSimpleObject.__init__(self, xax, yax)
         
         self.colour = colour
         self.width  = width
@@ -269,13 +281,17 @@ class Line(AnnotationObject):
     2D line.
     """
 
-    def __init__(self, xy1, xy2, *args, **kwargs):
+    def __init__(self, xax, yax, xy1, xy2, *args, **kwargs):
         """Create a ``Line`` annotation.
 
         The ``xy1`` and ``xy2`` coordinate tuples should be in relation to the
         axes which map to the horizontal/vertical screen axes on the target
         canvas.
 
+        :arg xax: Initial display X axis
+
+        :arg yax: Initial display Y axis        
+
         :arg xy1: Tuple containing the (x, y) coordinates of one endpoint.
         
         :arg xy2: Tuple containing the (x, y) coordinates of the second
@@ -284,7 +300,7 @@ class Line(AnnotationObject):
         All other arguments are passed through to
         :meth:`AnnotationObject.__init__`.
         """
-        AnnotationObject.__init__(self, *args, **kwargs)
+        AnnotationObject.__init__(self, xax, yax, *args, **kwargs)
         self.xy1 = xy1
         self.xy2 = xy2
 
@@ -310,18 +326,22 @@ class Rect(AnnotationObject):
     2D rectangle.
     """
 
-    def __init__(self, xy, w, h, *args, **kwargs):
+    def __init__(self, xax, yax, xy, w, h, *args, **kwargs):
         """Create a :class:`Rect` annotation.
 
-        :arg xy: Tuple specifying bottom left of the rectangle, in the display
-                 coordinate system.
-        :arg w:  Rectangle width.
-        :arg h:  Rectangle height.
+        :arg xax: Initial display X axis
+
+        :arg yax: Initial display Y axis        
+
+        :arg xy:  Tuple specifying bottom left of the rectangle, in the display
+                  coordinate system.
+        :arg w:   Rectangle width.
+        :arg h:   Rectangle height.
 
         All other arguments are passed through to
         :meth:`AnnotationObject.__init__`.        
         """
-        AnnotationObject.__init__(self, *args, **kwargs)
+        AnnotationObject.__init__(self, xax, yax, *args, **kwargs)
         self.xy = xy
         self.w  = w
         self.h  = h
@@ -371,6 +391,8 @@ class VoxelGrid(AnnotationObject):
 
     
     def __init__(self,
+                 xax,
+                 yax,
                  selectMask,
                  displayToVoxMat,
                  voxToDisplayMat,
@@ -379,6 +401,10 @@ class VoxelGrid(AnnotationObject):
                  **kwargs):
         """Create a ``VoxelGrid`` annotation.
 
+        :arg xax:             Initial display X axis
+
+        :arg yax:             Initial display Y axis        
+
         :arg selectMask:      A 3D numpy array, the same shape as the image
                               being annotated (or a sub-space of the image - 
                               see the ``offsets`` argument),  which is 
@@ -403,7 +429,7 @@ class VoxelGrid(AnnotationObject):
         """
         
         kwargs['xform'] = voxToDisplayMat
-        AnnotationObject.__init__(self, *args, **kwargs)
+        AnnotationObject.__init__(self, xax, yax, *args, **kwargs)
         
         if offsets is None:
             offsets = [0, 0, 0]
@@ -453,6 +479,8 @@ class VoxelSelection(AnnotationObject):
 
     
     def __init__(self,
+                 xax,
+                 yax,
                  selection,
                  displayToVoxMat,
                  voxToDisplayMat,
@@ -461,6 +489,10 @@ class VoxelSelection(AnnotationObject):
                  **kwargs):
         """Create a ``VoxelSelection`` annotation.
 
+        :arg xax:             Initial display X axis
+
+        :arg yax:             Initial display Y axis        
+
         :arg selection:       A :class:`.Selection` instance which defines
                               the voxels to be highlighted.
         
@@ -484,7 +516,7 @@ class VoxelSelection(AnnotationObject):
         :meth:`AnnotationObject.__init__` method.
         """
         
-        AnnotationObject.__init__(self, *args, **kwargs)
+        AnnotationObject.__init__(self, xax, yax, *args, **kwargs)
 
         if offsets is None:
             offsets = [0, 0, 0]
diff --git a/fsl/fsleyes/gl/gllabel.py b/fsl/fsleyes/gl/gllabel.py
index b01e27ad31bcd4d451cdff23f2312001def1cc39..a33ecb0a1d4091846d31f72ae6548d753e3a164a 100644
--- a/fsl/fsleyes/gl/gllabel.py
+++ b/fsl/fsleyes/gl/gllabel.py
@@ -43,20 +43,25 @@ class GLLabel(globject.GLImageObject):
     """
 
     
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLLabel``.
 
         :arg image:   The :class:`.Image` instance.
         :arg display: The associated :class:`.Display` instance.
+        :arg xax:     Initial display X axis
+        :arg yax:     Initial display Y axis        
         """
 
-        globject.GLImageObject.__init__(self, image, display)
-
-        lutTexName   = '{}_lut'.format(self.name)
+        globject.GLImageObject.__init__(self, image, display, xax, yax)
 
+        lutTexName        = '{}_lut'.format(self.name)
         self.lutTexture   = textures.LookupTableTexture(lutTexName)
         self.imageTexture = None
 
+        # The shader attribute will be created 
+        # by the gllabel_funcs module
+        self.shader       = None
+
         self.addListeners()
 
         self.refreshLutTexture()
@@ -86,7 +91,9 @@ class GLLabel(globject.GLImageObject):
         """Returns ``True`` if this ``GLLabel`` is ready to be drawn, ``False``
         otherwise.
         """
-        return self.imageTexture is not None and self.imageTexture.ready()
+        return self.shader       is not None and \
+               self.imageTexture is not None and \
+               self.imageTexture.ready()
 
 
     def addListeners(self):
diff --git a/fsl/fsleyes/gl/gllinevector.py b/fsl/fsleyes/gl/gllinevector.py
index 1549f9bdd5e9eb1313455054f429d2668b074814..fce6f809f1bc95820a2b9e1ac1850031ec482309 100644
--- a/fsl/fsleyes/gl/gllinevector.py
+++ b/fsl/fsleyes/gl/gllinevector.py
@@ -53,12 +53,13 @@ class GLLineVector(glvector.GLVector):
     """
 
 
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLLineVector`` instance.
 
         :arg image:   An :class:`.Image` or :class:`.TensorImage` instance.
-
         :arg display: The associated :class:`.Display` instance.
+        :arg xax:     Initial display X axis
+        :arg yax:     Initial display Y axis
         """
         
         # If the overlay is a TensorImage, use the
@@ -70,6 +71,8 @@ class GLLineVector(glvector.GLVector):
         glvector.GLVector.__init__(self,
                                    image,
                                    display,
+                                   xax,
+                                   yax,
                                    vectorImage=vecImage,
                                    init=lambda: fslgl.gllinevector_funcs.init(
                                        self))
diff --git a/fsl/fsleyes/gl/glmodel.py b/fsl/fsleyes/gl/glmodel.py
index 0dd61055d9b2631825d14e2eab06a83d2104b9b2..0e348889ee4716e777f7d36b571e24ed68c7e74b 100644
--- a/fsl/fsleyes/gl/glmodel.py
+++ b/fsl/fsleyes/gl/glmodel.py
@@ -65,16 +65,20 @@ class GLModel(globject.GLObject):
     """
 
     
-    def __init__(self, overlay, display):
+    def __init__(self, overlay, display, xax, yax):
         """Create a ``GLModel``.
 
         :arg overlay: A :class:`.Model` overlay.
 
         :arg display: A :class:`.Display` instance defining how the
                       ``overlay`` is to be displayed.
+        
+        :arg xax:     Initial display X axis
+
+        :arg yax:     Initial display Y axis        
         """
 
-        globject.GLObject.__init__(self)
+        globject.GLObject.__init__(self, xax, yax)
 
         self.shader  = None
         self.overlay = overlay
diff --git a/fsl/fsleyes/gl/globject.py b/fsl/fsleyes/gl/globject.py
index 3c03d030e594c6b14bb1c216246b07a4e20bd83b..72fbc67e0dfc7730cdc7c262d8f5179be7afcd52 100644
--- a/fsl/fsleyes/gl/globject.py
+++ b/fsl/fsleyes/gl/globject.py
@@ -50,7 +50,7 @@ def getGLObjectType(overlayType):
     return typeMap.get(overlayType, None)
 
 
-def createGLObject(overlay, display):
+def createGLObject(overlay, display, xax, yax):
     """Create :class:`GLObject` instance for the given overlay, as specified
     by the :attr:`.Display.overlayType` property.
 
@@ -58,10 +58,14 @@ def createGLObject(overlay, display):
     
     :arg display: A :class:`.Display` instance describing how the overlay
                   should be displayed.
+
+    :arg xax:     Initial display X axis
+
+    :arg yax:     Initial display Y axis    
     """
     ctr = getGLObjectType(display.overlayType)
 
-    if ctr is not None: return ctr(overlay, display)
+    if ctr is not None: return ctr(overlay, display, xax, yax)
     else:               return None
 
 
@@ -104,7 +108,11 @@ class GLObject(notifier.Notifier):
     
     Sub-class implementations must do the following:
     
-     - Call :meth:`__init__`.
+     - Call :meth:`__init__`. A ``GLObject.__init__`` sub-class method must
+       have the following signature::
+    
+           def __init__(self, overlay, display, xax, yax)
+    
 
      - Call :meth:`notify` whenever its OpenGL representation changes.
 
@@ -132,23 +140,26 @@ class GLObject(notifier.Notifier):
     """
 
     
-    def __init__(self):
-        """Create a :class:`GLObject`.  The constructor adds one attribute
+    def __init__(self, xax, yax):
+        """Create a :class:`GLObject`.  The constructor adds one attribute 
         to this instance, ``name``, which is simply a unique name for this
-        instance, and gives default values to the ``xax``, ``yax``, and
-        ``zax`` attributes.
+        instance, and gives values to the ``xax``, ``yax``, and ``zax``
+        attributes.
 
         Subclass implementations must call this method, and should also
         perform any necessary OpenGL initialisation, such as creating
         textures.
+
+        :arg xax: Initial display X axis
+        :arg yax: Initial display Y axis
         """
 
         # Give this instance a name, and set 
         # initial values for the display axes
         self.name = '{}_{}'.format(type(self).__name__, id(self))
-        self.xax  = 0
-        self.yax  = 1
-        self.zax  = 2
+        self.xax  = xax
+        self.yax  = yax
+        self.zax  = 3 - xax - yax
 
         log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
 
@@ -285,9 +296,9 @@ class GLSimpleObject(GLObject):
     be called.
     """
 
-    def __init__(self):
+    def __init__(self, xax, yax):
         """Create a ``GLSimpleObject``. """
-        GLObject.__init__(self)
+        GLObject.__init__(self, xax, yax)
 
 
     def ready(self):
@@ -315,7 +326,7 @@ class GLImageObject(GLObject):
     of :class:`.Nifti1` instances. 
     """
     
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLImageObject``.
 
         This constructor adds the following attributes to this instance:
@@ -333,9 +344,13 @@ class GLImageObject(GLObject):
         :arg image:   The :class:`.Nifti1` instance
         
         :arg display: An associated :class:`.Display` instance.
+
+        :arg xax:     Initial display X axis
+
+        :arg yax:     Initial display Y axis
         """
         
-        GLObject.__init__(self)
+        GLObject.__init__(self, xax, yax)
         self.image       = image
         self.display     = display
         self.displayOpts = display.getDisplayOpts()
diff --git a/fsl/fsleyes/gl/glrgbvector.py b/fsl/fsleyes/gl/glrgbvector.py
index 5d290dd506ace290f48abe8b9bebda278f5970ad..4c25bd4f51f9639617c81ad32f3d6120c65e4420 100644
--- a/fsl/fsleyes/gl/glrgbvector.py
+++ b/fsl/fsleyes/gl/glrgbvector.py
@@ -59,11 +59,13 @@ class GLRGBVector(glvector.GLVector):
     """
 
 
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLRGBVector``.
 
         :arg image:   An :class:`.Image` or :class:`.TensorImage` instance.
         :arg display: The associated :class:`.Display` instance.
+        :arg xax:     Initial display X axis
+        :arg yax:     Initial display Y axis        
         """
 
         # If the overlay is a TensorImage, use the
@@ -75,6 +77,8 @@ class GLRGBVector(glvector.GLVector):
         glvector.GLVector.__init__(self,
                                    image,
                                    display,
+                                   xax,
+                                   yax,
                                    prefilter=np.abs,
                                    vectorImage=vecImage,
                                    init=lambda: fslgl.glrgbvector_funcs.init(
diff --git a/fsl/fsleyes/gl/gltensor.py b/fsl/fsleyes/gl/gltensor.py
index 96f8e7d68bbd91d840a1136ea41e9baf33005279..064adc63da314730aa0fc9fe847cfafa28de6ec5 100644
--- a/fsl/fsleyes/gl/gltensor.py
+++ b/fsl/fsleyes/gl/gltensor.py
@@ -28,7 +28,7 @@ class GLTensor(glvector.GLVector):
     """
 
     
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLTensor``. Calls the :func:`.gl21.gltensor_funcs.init`
         function.
 
@@ -36,10 +36,16 @@ class GLTensor(glvector.GLVector):
         
         :arg display: The :class:`.Display` instance associated with the
                       ``image``.
+        
+        :arg xax:     Initial display X axis
+
+        :arg yax:     Initial display Y axis        
         """
         glvector.GLVector.__init__(self,
                                    image,
                                    display,
+                                   xax,
+                                   yax,
                                    prefilter=np.abs,
                                    vectorImage=image.V1(),
                                    init=lambda: fslgl.gltensor_funcs.init(
diff --git a/fsl/fsleyes/gl/glvector.py b/fsl/fsleyes/gl/glvector.py
index a05935eff28486b9befa3428c0df3ed63b7242e6..f47b6fc7a64423e5123da84baa999727b569cb11 100644
--- a/fsl/fsleyes/gl/glvector.py
+++ b/fsl/fsleyes/gl/glvector.py
@@ -96,6 +96,8 @@ class GLVector(globject.GLImageObject):
     def __init__(self,
                  image,
                  display,
+                 xax,
+                 yax,
                  prefilter=None,
                  vectorImage=None,
                  init=None):
@@ -116,6 +118,10 @@ class GLVector(globject.GLImageObject):
         :arg display:     A :class:`.Display` object which describes how the
                           image is to be displayed.
 
+        :arg xax:         Initial display X axis
+
+        :arg yax:         Initial display Y axis        
+
         :arg prefilter:   An optional function which filters the data before it
                           is stored as a 3D texture. See
                           :class:`.ImageTexture`. Whether or not this function
@@ -145,7 +151,7 @@ class GLVector(globject.GLImageObject):
             raise ValueError('Image must be 4 dimensional, with 3 volumes '
                              'representing the XYZ vector angles')
 
-        globject.GLImageObject.__init__(self, image, display)
+        globject.GLImageObject.__init__(self, image, display, xax, yax)
 
         name = self.name
 
diff --git a/fsl/fsleyes/gl/glvolume.py b/fsl/fsleyes/gl/glvolume.py
index e04fa19dde427adec8045e175daf1044bbc8dde1..3eb8125ac25889f55ea633c6b813993eed9d02bb 100644
--- a/fsl/fsleyes/gl/glvolume.py
+++ b/fsl/fsleyes/gl/glvolume.py
@@ -142,16 +142,20 @@ class GLVolume(globject.GLImageObject):
     """
 
     
-    def __init__(self, image, display):
+    def __init__(self, image, display, xax, yax):
         """Create a ``GLVolume`` object.
 
         :arg image:   An :class:`.Image` object.
         
         :arg display: A :class:`.Display` object which describes how the image
                       is to be displayed.
+
+        :arg xax:     Initial display X axis
+
+        :arg yax:     Initial display Y axis 
         """
 
-        globject.GLImageObject.__init__(self, image, display)
+        globject.GLImageObject.__init__(self, image, display, xax, yax)
 
         # Add listeners to this image so the view can be
         # updated when its display properties are changed
diff --git a/fsl/fsleyes/gl/slicecanvas.py b/fsl/fsleyes/gl/slicecanvas.py
index 0b3d700d17f916fdf69433430243e8093bbfbf12..5ce14d3dfaeec264e907b2c60285a78162f84ec4 100644
--- a/fsl/fsleyes/gl/slicecanvas.py
+++ b/fsl/fsleyes/gl/slicecanvas.py
@@ -802,10 +802,12 @@ class SliceCanvas(props.HasProperties):
                 self._glObjects.pop(overlay)
                 return
 
-            globj = globject.createGLObject(overlay, display)
+            globj = globject.createGLObject(overlay,
+                                            display,
+                                            self.xax,
+                                            self.yax)
 
             if globj is not None:
-                globj.setAxes(self.xax, self.yax)
                 globj.register(self.name, self._refresh)
 
             self._glObjects[overlay] = globj