diff --git a/fsl/data/melodicimage.py b/fsl/data/melodicimage.py
index f3b628810e332213a8ec3487a71773c983063b80..258e5663288956e718205404ddd67ce72bc71e28 100644
--- a/fsl/data/melodicimage.py
+++ b/fsl/data/melodicimage.py
@@ -79,9 +79,11 @@ class MelodicImage(fslimage.Image):
                                 *args,
                                 **kwargs)
 
-        self.__meldir   = dirname
-        self.__melmix   = melresults.getComponentTimeSeries(  dirname)
-        self.__melFTmix = melresults.getComponentPowerSpectra(dirname)
+        self.__meldir     = dirname
+        self.__melmix     = melresults.getComponentTimeSeries(  dirname)
+        self.__melFTmix   = melresults.getComponentPowerSpectra(dirname)
+        self.__melICClass = melresults.MelodicClassification(
+            self.numComponents())
 
         # Automatically set the
         # TR value if possible
@@ -92,6 +94,8 @@ class MelodicImage(fslimage.Image):
             if dataImage.is4DImage():
                 self.tr = dataImage.pixdim[3]
 
+        # TODO load classifications if present
+
         
     def getComponentTimeSeries(self, component):
         """Returns the time course for the specified (0-indexed) component. """
@@ -125,3 +129,7 @@ class MelodicImage(fslimage.Image):
         :func:`.melodicresults.getDataFile` function.
         """
         return melresults.getDataFile(self.__meldir)
+
+
+    def getICClassification(self):
+        return self.__melICClass
diff --git a/fsl/data/melodicresults.py b/fsl/data/melodicresults.py
index 105c1ae28aa31dbbbd7f6ae5064dc033aa007dce..85a538198513cd4a1a44841fc2d6eb0922335cac 100644
--- a/fsl/data/melodicresults.py
+++ b/fsl/data/melodicresults.py
@@ -179,3 +179,82 @@ def getComponentPowerSpectra(meldir):
     """
     ftmixfile = getFTMixFile(meldir)
     return np.loadtxt(ftmixfile)
+
+
+
+class MelodicClassification(object):
+    """
+    """
+
+    def __init__(self, ncomps):
+        """Create a ``MelodicClassification`` instance.
+        """
+
+        self.__ncomps          = ncomps
+
+        self.__componentLabels = [[] for i in range(ncomps)]
+        self.__labelComponents = {}
+
+
+    def load(self, filename):
+        pass
+
+    
+    def save(self, filename):
+        pass 
+
+
+    def getLabels(self, component):
+        return list(self.__componentLabels[component])
+    
+
+    def addLabel(self, component, label):
+
+        cmpLabels = self.__componentLabels[component]
+        labelCmps = self.__labelComponents.get(label, [])
+        
+        if label in cmpLabels:
+            return 
+
+        cmpLabels[component].append(label)
+        labelCmps[label]    .append(component)
+
+        self.__componentLabels[component] = cmpLabels
+        self.__labelComponents[label]     = labelCmps
+ 
+
+    def removeLabel(self, component, label):
+
+        if label not in self.__componentLabels[component]:
+            return
+
+        self.__componentLabels[component].remove(label)
+        self.__labelComponents[label]    .remove(component)
+
+    
+    def clearLabels(self, component):
+        
+        labels = self.getLabels(component)
+
+        for l in labels:
+            self.removeLabel(component, l)
+
+    
+    def getComponents(self, label):
+        return list(self.__labelComponents.get(label, []))
+
+    
+    def addComponent(self, label, component):
+        self.addLabel(component, label)
+
+
+    def removeComponent(self, label, component):
+        self.removeLabel(component, label)
+
+    
+    def clearComponents(self, label):
+        
+        components = self.getComponents(label)
+
+        for c in components:
+            self.removeComponent(label, c) 
diff --git a/fsl/data/strings.py b/fsl/data/strings.py
index 14621ff482b00e3cb434a23b05ff8195ba7a644c..3a761984607d6bc13514c56cbe9211fc7240c6a2 100644
--- a/fsl/data/strings.py
+++ b/fsl/data/strings.py
@@ -122,6 +122,9 @@ messages = TypeDict({
     'OrthoEditProfile.displaySpaceChange' : 'Setting {} as the display '
                                             'space reference image - this '
                                             'is necessary for editing.',
+
+
+    'MelodicClassificationPanel.disabled' : 'Choose a melodic image.',
 })
 
 
@@ -173,6 +176,8 @@ titles = TypeDict({
     'OverlayInfoPanel'          : 'Overlay information',
     'ShellPanel'                : 'Python shell',
 
+    'MelodicClassificationPanel' : 'Melodic IC classification',
+
     'LookupTablePanel.loadLut'     : 'Select a lookup table file',
     'LookupTablePanel.labelExists' : 'Label already exists',
 })
@@ -188,17 +193,18 @@ actions = TypeDict({
 
     'FSLEyesFrame.closeViewPanel' : 'Close',
 
-    'CanvasPanel.screenshot'              : 'Take screenshot',
-    'CanvasPanel.showCommandLineArgs'     : 'Show command line for scene',
-    'CanvasPanel.toggleColourBar'         : 'Colour bar',
-    'CanvasPanel.toggleOverlayList'       : 'Overlay list',
-    'CanvasPanel.toggleDisplayProperties' : 'Overlay display properties',
-    'CanvasPanel.toggleLocationPanel'     : 'Location panel',
-    'CanvasPanel.toggleAtlasPanel'        : 'Atlas panel',
-    'CanvasPanel.toggleLookupTablePanel'  : 'Lookup tables',
-    'CanvasPanel.toggleClusterPanel'      : 'Cluster browser',
-    'CanvasPanel.toggleOverlayInfo'       : 'Overlay information',
-    'CanvasPanel.toggleShell'             : 'Python shell',
+    'CanvasPanel.screenshot'                : 'Take screenshot',
+    'CanvasPanel.showCommandLineArgs'       : 'Show command line for scene',
+    'CanvasPanel.toggleColourBar'           : 'Colour bar',
+    'CanvasPanel.toggleOverlayList'         : 'Overlay list',
+    'CanvasPanel.toggleDisplayProperties'   : 'Overlay display properties',
+    'CanvasPanel.toggleLocationPanel'       : 'Location panel',
+    'CanvasPanel.toggleAtlasPanel'          : 'Atlas panel',
+    'CanvasPanel.toggleLookupTablePanel'    : 'Lookup tables',
+    'CanvasPanel.toggleClusterPanel'        : 'Cluster browser',
+    'CanvasPanel.toggleOverlayInfo'         : 'Overlay information',
+    'CanvasPanel.toggleClassificationPanel' : 'Melodic IC classification',
+    'CanvasPanel.toggleShell'               : 'Python shell',
     
     'OrthoPanel.toggleOrthoToolBar'     : 'View properties',
     'OrthoPanel.toggleEditToolBar'      : 'Edit toolbar',
diff --git a/fsl/fsleyes/controls/melodicclassificationpanel.py b/fsl/fsleyes/controls/melodicclassificationpanel.py
new file mode 100644
index 0000000000000000000000000000000000000000..861c96c44493cfa9c749f00ee21a2854165ccaf8
--- /dev/null
+++ b/fsl/fsleyes/controls/melodicclassificationpanel.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+#
+# melodicclassificationpanel.py - The MelodicClassificationPanel class.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides the :class:`MelodicClassificationPanel` class, a
+*FSLeyes control* panel which allows the user to classify the components
+of a :class:`.MelodicImage`.
+"""
+
+import wx
+
+
+import pwidgets.widgetgrid as widgetgrid
+import pwidgets.texttag    as texttag
+import pwidgets.notebook   as notebook
+
+import fsl.data.strings      as strings
+import fsl.data.melodicimage as fslmelimage
+import fsl.fsleyes.panel     as fslpanel
+
+
+class MelodicClassificationPanel(fslpanel.FSLEyesPanel):
+    """The ``MelodicClassificationPanel``
+    """
+
+    # 
+    # Choose label colours
+    # Load/save from/to file
+    #
+    def __init__(self, parent, overlayList, displayCtx):
+        """Create a ``MelodicClassificationPanel``.
+
+        :arg parent:      The :mod:`wx` parent object.
+        
+        :arg overlayList: The :class:`.OverlayList`.
+        
+        :arg displayCtx:  The :class:`.DisplayContext` instance.
+        """ 
+        fslpanel.FSLEyesPanel.__init__(self, parent, overlayList, displayCtx)
+
+        self.__disabledText = wx.StaticText(
+            self,
+            style=(wx.ALIGN_CENTRE_HORIZONTAL |
+                   wx.ALIGN_CENTRE_VERTICAL))
+
+        self.__notebook      = notebook.Notebook(self)
+        self.__componentGrid = ComponentGrid(    self.__notebook)
+        self.__labelGrid     = LabelGrid(        self.__notebook)
+
+        self.__notebook.AddPage(self.__componentGrid, 'Components')
+        self.__notebook.AddPage(self.__labelGrid,     'Labels')
+
+        self.__mainSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.__mainSizer.Add(self.__notebook, flag=wx.EXPAND, proportion=1)
+
+        # TODO Things which you don't want shown when
+        #      a melodic image is not selected should
+        #      be added to __mainSizer. Things which
+        #      you always want displayed should be
+        #      added to __sizer (but need to be laid
+        #      out w.r.t. __disabledText/__mainSizer)
+
+        self.__sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.__sizer.Add(self.__disabledText, flag=wx.EXPAND, proportion=1)
+        self.__sizer.Add(self.__mainSizer,    flag=wx.EXPAND, proportion=1)
+
+        self.SetSizer(self.__sizer)
+
+        overlayList.addListener('overlays',
+                                self._name,
+                                self.__selectedOverlayChanged)
+        displayCtx .addListener('selectedOverlay',
+                                self._name,
+                                self.__selectedOverlayChanged)
+
+        self.__overlay = None
+        self.__selectedOverlayChanged()
+
+
+    def destroy(self):
+        """
+        """
+        self._displayCtx .removeListener('selectedOverlay', self._name)
+        self._overlayList.removeListener('overlays',        self._name)
+        fslpanel.FSLEyesPanel.destroy(self)
+
+
+    def __enable(self, enable=True, message=''):
+        """
+        """
+
+        self.__disabledText.SetLabel(message)
+        
+        self.__sizer.Show(self.__disabledText, not enable)
+        self.__sizer.Show(self.__mainSizer,    enable)
+
+        self.Layout()
+
+
+    def __selectedOverlayChanged(self, *a):
+
+        overlay = self._displayCtx.getSelectedOverlay()
+
+        if (overlay is None) or \
+           not isinstance(overlay, fslmelimage.MelodicImage):
+            self.__enable(False, strings.messages[self, 'disabled'])
+            return
+
+        self.__overlay = overlay
+
+        self.__componentGrid.setOverlay(overlay)
+        self.__labelGrid    .setOverlay(overlay)
+
+        self.__enable(True)
+
+
+class ComponentGrid(wx.Panel):
+
+    def __init__(self, parent):
+        wx.Panel.__init__(self, parent)
+
+        self.__grid  = widgetgrid.WidgetGrid(self)
+        self.__sizer = wx.BoxSizer(wx.HORIZONTAL)
+
+        self.__grid.ShowRowLabels(False)
+        self.__grid.ShowColLabels(True)
+        
+        self.__sizer.Add(self.__grid, flag=wx.EXPAND, proportion=1)
+
+        self.SetSizer(self.__sizer)
+
+        
+    def setOverlay(self, overlay):
+
+        numComps = overlay.numComponents()
+
+        self.__grid.ClearGrid()
+        self.__grid.SetGridSize(numComps, 2, growCols=[1])
+
+        self.__grid.SetColLabel(0, 'Component #')
+        self.__grid.SetColLabel(1, 'Labels')
+
+        for i in range(numComps):
+
+            tags = texttag.TextTagPanel(self.__grid,
+                                        style=(texttag.TTP_ALLOW_NEW_TAGS |
+                                               texttag.TTP_ADD_NEW_TAGS   |
+                                               texttag.TTP_NO_DUPLICATES))
+            
+            self.__grid.SetText(  i, 0, str(i))
+            self.__grid.SetWidget(i, 1, tags)
+
+        self.Layout()
+        
+        
+
+class LabelGrid(wx.Panel):
+
+    def __init__(self, parent):
+        
+        wx.Panel.__init__(self, parent)
+
+        self.__grid  = widgetgrid.WidgetGrid(self)
+        self.__sizer = wx.BoxSizer(wx.HORIZONTAL)
+        
+        self.__sizer.Add(self.__grid, flag=wx.EXPAND, proportion=1)
+
+        self.SetSizer(self.__sizer) 
+
+        
+    def setOverlay(self, overlay):
+        pass
diff --git a/fsl/fsleyes/views/canvaspanel.py b/fsl/fsleyes/views/canvaspanel.py
index 4ca4ad4068d0bdd2d7ecd5ff81c84f746edc768e..3822151e78eae02c5f4eae506c3f5640583641dd 100644
--- a/fsl/fsleyes/views/canvaspanel.py
+++ b/fsl/fsleyes/views/canvaspanel.py
@@ -21,23 +21,23 @@ import matplotlib.image as mplimg
 
 import props
 
-import fsl.fsleyes.fsleyes_parseargs              as fsleyes_parseargs
-import fsl.utils.dialog                           as fsldlg
-import fsl.utils.settings                         as fslsettings
-import fsl.data.image                             as fslimage
-import fsl.data.strings                           as strings
-import fsl.fsleyes.displaycontext                 as displayctx
-import fsl.fsleyes.controls.overlaylistpanel      as overlaylistpanel
-import fsl.fsleyes.controls.overlayinfopanel      as overlayinfopanel
-import fsl.fsleyes.controls.atlaspanel            as atlaspanel
-import fsl.fsleyes.controls.overlaydisplaytoolbar as overlaydisplaytoolbar
-import fsl.fsleyes.controls.locationpanel         as locationpanel
-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 fsl.fsleyes.fsleyes_parseargs                   as fsleyes_parseargs
+import fsl.utils.dialog                                as fsldlg
+import fsl.utils.settings                              as fslsettings
+import fsl.data.image                                  as fslimage
+import fsl.data.strings                                as strings
+import fsl.fsleyes.displaycontext                      as displayctx
+import fsl.fsleyes.controls.overlaylistpanel           as overlaylistpanel
+import fsl.fsleyes.controls.overlayinfopanel           as overlayinfopanel
+import fsl.fsleyes.controls.atlaspanel                 as atlaspanel
+import fsl.fsleyes.controls.overlaydisplaytoolbar      as overlaydisplaytoolbar
+import fsl.fsleyes.controls.locationpanel              as locationpanel
+import fsl.fsleyes.controls.clusterpanel               as clusterpanel
+import fsl.fsleyes.controls.lookuptablepanel           as lookuptablepanel
+import fsl.fsleyes.controls.melodicclassificationpanel as melclasspanel
+import fsl.fsleyes.controls.shellpanel                 as shellpanel
+import                                                    colourbarpanel
+import                                                    viewpanel
 
 
 log = logging.getLogger(__name__)
@@ -84,16 +84,18 @@ class CanvasPanel(viewpanel.ViewPanel):
     :mod:`control <.controls>` panels:
     
     
-    =========================== ===========================================
-    ``toggleOverlayList``       Toggles an :class:`.OverlayListPanel`.
-    ``toggleOverlayInfo``       Toggles an :class:`.OverlayInfoPanel`.
-    ``toggleAtlasPanel``        Toggles an :class:`.AtlasPanel`.
-    ``toggleDisplayProperties`` Toggles an :class:`.OverlayDisplayToolBar`.
-    ``toggleLocationPanel``     Toggles a :class:`.LocationPanel`.
-    ``toggleClusterPanel``      Toggles a :class:`.ClusterPanel`.
-    ``toggleLookupTablePanel``  Toggles a :class:`.LookupTablePanel`.
-    ``toggleShell``             Toggles a :class:`.ShellPanel`.
-    =========================== ===========================================
+    ============================== ===========================================
+    ``toggleOverlayList``          Toggles an :class:`.OverlayListPanel`.
+    ``toggleOverlayInfo``          Toggles an :class:`.OverlayInfoPanel`.
+    ``toggleAtlasPanel``           Toggles an :class:`.AtlasPanel`.
+    ``toggleDisplayProperties``    Toggles an :class:`.OverlayDisplayToolBar`.
+    ``toggleLocationPanel``        Toggles a :class:`.LocationPanel`.
+    ``toggleClusterPanel``         Toggles a :class:`.ClusterPanel`.
+    ``toggleLookupTablePanel``     Toggles a :class:`.LookupTablePanel`.
+    ``toggleClassificationPanel``  Toggles a
+                                   :class:`.MelodicClassificationPanel`.
+    ``toggleShell``                Toggles a :class:`.ShellPanel`.
+    ============================== ===========================================
 
     
     A couple of other actions are also provided, with the same names as their
@@ -246,29 +248,32 @@ class CanvasPanel(viewpanel.ViewPanel):
             extraActions = {}
 
         actionz = [
-            ('screenshot',              self.screenshot),
-            ('showCommandLineArgs',     self.showCommandLineArgs),
-            ('toggleOverlayList',       lambda *a: self.togglePanel(
+            ('screenshot',                self.screenshot),
+            ('showCommandLineArgs',       self.showCommandLineArgs),
+            ('toggleOverlayList',         lambda *a: self.togglePanel(
                 overlaylistpanel.OverlayListPanel,
                 location=wx.BOTTOM)),
-            ('toggleOverlayInfo',       lambda *a: self.togglePanel(
+            ('toggleOverlayInfo',         lambda *a: self.togglePanel(
                 overlayinfopanel.OverlayInfoPanel,
-                location=wx.RIGHT)), 
-            ('toggleAtlasPanel',        lambda *a: self.togglePanel(
+                location=wx.LEFT)), 
+            ('toggleAtlasPanel',          lambda *a: self.togglePanel(
                 atlaspanel.AtlasPanel,
                 location=wx.BOTTOM)),
-            ('toggleDisplayProperties', lambda *a: self.togglePanel(
+            ('toggleDisplayProperties',   lambda *a: self.togglePanel(
                 overlaydisplaytoolbar.OverlayDisplayToolBar,
                 viewPanel=self)),
-            ('toggleLocationPanel',     lambda *a: self.togglePanel(
+            ('toggleLocationPanel',       lambda *a: self.togglePanel(
                 locationpanel.LocationPanel,
                 location=wx.BOTTOM)),
-            ('toggleClusterPanel',      lambda *a: self.togglePanel(
+            ('toggleClusterPanel',        lambda *a: self.togglePanel(
                 clusterpanel.ClusterPanel,
                 location=wx.TOP)), 
-            ('toggleLookupTablePanel',  lambda *a: self.togglePanel(
+            ('toggleLookupTablePanel',    lambda *a: self.togglePanel(
                 lookuptablepanel.LookupTablePanel,
-                location=wx.TOP))]
+                location=wx.TOP)),
+            ('toggleClassificationPanel', lambda *a: self.togglePanel(
+                melclasspanel.MelodicClassificationPanel,
+                location=wx.RIGHT))]
 
         actionz += extraActions.items()