diff --git a/fsl/data/melodicimage.py b/fsl/data/melodicimage.py
index 3a2087da9a028717e832374be773ff89d3d07dfc..f3b628810e332213a8ec3487a71773c983063b80 100644
--- a/fsl/data/melodicimage.py
+++ b/fsl/data/melodicimage.py
@@ -26,10 +26,13 @@ class MelodicImage(fslimage.Image):
     The ``MelodicImage`` class provides a few MELODIC-specific attributes and
     methods:
 
+    
     .. autosummary::
+       :nosignatures:
 
        tr
        getComponentTimeSeries
+       getComponentPowerSpectrum
        numComponents
        getTopLevelAnalysisDir
        getDataFile
@@ -76,8 +79,9 @@ class MelodicImage(fslimage.Image):
                                 *args,
                                 **kwargs)
 
-        self.__meldir = dirname
-        self.__melmix = melresults.getComponentTimeSeries(dirname)
+        self.__meldir   = dirname
+        self.__melmix   = melresults.getComponentTimeSeries(  dirname)
+        self.__melFTmix = melresults.getComponentPowerSpectra(dirname)
 
         # Automatically set the
         # TR value if possible
@@ -93,6 +97,13 @@ class MelodicImage(fslimage.Image):
         """Returns the time course for the specified (0-indexed) component. """
         return self.__melmix[:, component]
 
+    
+    def getComponentPowerSpectrum(self, component):
+        """Returns the power spectrum for the time course of the specified
+        (0-indexed) component.
+        """
+        return self.__melFTmix[:, component] 
+
 
     def numComponents(self):
         """Returns the number of components in this ``MelodicImage``. """
diff --git a/fsl/data/melodicresults.py b/fsl/data/melodicresults.py
index c31811723bd78e2ce8036072d3c5d3f0e19734d5..105c1ae28aa31dbbbd7f6ae5064dc033aa007dce 100644
--- a/fsl/data/melodicresults.py
+++ b/fsl/data/melodicresults.py
@@ -10,8 +10,9 @@ MELODIC analysis directory. These functions are primarily intended to be used
 by the :class:`.MELODICImage` class, but are available for other uses. The
 following functions are provided:
 
+
 .. autosummary::
-   nosignatures:
+   :nosignatures:
 
    isMelodicDir
    getMelodicDir
@@ -19,8 +20,10 @@ following functions are provided:
    getDataFile
    getICFile
    getMixFile
+   getFTMixFile
    getNumComponents
    getComponentTimeSeries
+   getComponentPowerSpectra
 """
 
 
@@ -74,9 +77,10 @@ def getMelodicDir(path):
     except ValueError:
         return None
 
-    # Must contain a file called melodic_mix
-    if not op.exists(op.join(path, 'melodic_mix')):
-        return None
+    # Must contain files called
+    # melodic_mix and melodic_FTmix
+    if not op.exists(op.join(path, 'melodic_mix')):   return None
+    if not op.exists(op.join(path, 'melodic_FTmix')): return None
                                            
     return path
 
@@ -142,6 +146,11 @@ def getMixFile(meldir):
     return op.join(meldir, 'melodic_mix')
 
 
+def getFTMixFile(meldir):
+    """Returns the path to the melodic FT mix file. """
+    return op.join(meldir, 'melodic_FTmix')
+
+
 def getReportFile(meldir):
     pass
 
@@ -162,3 +171,11 @@ def getComponentTimeSeries(meldir):
 
     mixfile = getMixFile(meldir)
     return np.loadtxt(mixfile)
+
+
+def getComponentPowerSpectra(meldir):
+    """Returns a ``numpy`` array containing the melodic FT mix for the
+    given directory.
+    """
+    ftmixfile = getFTMixFile(meldir)
+    return np.loadtxt(ftmixfile)
diff --git a/fsl/data/strings.py b/fsl/data/strings.py
index a3846b2c83f02d6e3ac6394ebd5567a5fcff6ce7..8bd5e9353a88316f071568311df5eb672fa77d33 100644
--- a/fsl/data/strings.py
+++ b/fsl/data/strings.py
@@ -137,10 +137,11 @@ titles = TypeDict({
     
     'overlay.loadOverlays.error'  : 'Error loading overlay',
 
-    'OrthoPanel'      : 'Ortho View',
-    'LightBoxPanel'   : 'Lightbox View',
-    'TimeSeriesPanel' : 'Time series',
-    'HistogramPanel'  : 'Histogram',
+    'OrthoPanel'         : 'Ortho View',
+    'LightBoxPanel'      : 'Lightbox View',
+    'TimeSeriesPanel'    : 'Time series',
+    'PowerSpectrumPanel' : 'Power spectra',
+    'HistogramPanel'     : 'Histogram',
 
     'CanvasPanel.screenshot'          : 'Save screenshot',
     'CanvasPanel.screenshot.notSaved' : 'Save overlay before continuing',
@@ -151,25 +152,26 @@ titles = TypeDict({
     'AtlasInfoPanel'      : 'Atlas information',
     'AtlasOverlayPanel'   : 'Atlas overlays',
 
-    'OverlayListPanel'       : 'Overlay list',
-    'AtlasPanel'             : 'Atlases',
-    'LocationPanel'          : 'Location',
-    'OverlayDisplayToolBar'  : 'Display toolbar',
-    'CanvasSettingsPanel'    : 'View settings',
-    'OverlayDisplayPanel'    : 'Display settings',
-    'OrthoToolBar'           : 'Ortho view toolbar',
-    'OrthoEditToolBar'       : 'Ortho view edit toolbar',
-    'LightBoxToolBar'        : 'Lightbox view toolbar',
-    'LookupTablePanel'       : 'Lookup tables',
-    'LutLabelDialog'         : 'New LUT label',
-    'NewLutDialog'           : 'New LUT',
-    'TimeSeriesListPanel'    : 'Time series list',
-    'TimeSeriesControlPanel' : 'Time series control',
-    'HistogramListPanel'     : 'Histogram list',
-    'HistogramControlPanel'  : 'Histogram control',
-    'ClusterPanel'           : 'Cluster browser',
-    'OverlayInfoPanel'       : 'Overlay information',
-    'ShellPanel'             : 'Python shell',
+    'OverlayListPanel'          : 'Overlay list',
+    'AtlasPanel'                : 'Atlases',
+    'LocationPanel'             : 'Location',
+    'OverlayDisplayToolBar'     : 'Display toolbar',
+    'CanvasSettingsPanel'       : 'View settings',
+    'OverlayDisplayPanel'       : 'Display settings',
+    'OrthoToolBar'              : 'Ortho view toolbar',
+    'OrthoEditToolBar'          : 'Ortho view edit toolbar',
+    'LightBoxToolBar'           : 'Lightbox view toolbar',
+    'LookupTablePanel'          : 'Lookup tables',
+    'LutLabelDialog'            : 'New LUT label',
+    'NewLutDialog'              : 'New LUT',
+    'TimeSeriesListPanel'       : 'Time series list',
+    'TimeSeriesControlPanel'    : 'Time series control',
+    'HistogramListPanel'        : 'Histogram list',
+    'HistogramControlPanel'     : 'Histogram control',
+    'PowerSpectrumControlPanel' : 'Power spectrum control',
+    'ClusterPanel'              : 'Cluster browser',
+    'OverlayInfoPanel'          : 'Overlay information',
+    'ShellPanel'                : 'Python shell',
 
     'LookupTablePanel.loadLut'     : 'Select a lookup table file',
     'LookupTablePanel.labelExists' : 'Label already exists',
@@ -207,11 +209,13 @@ actions = TypeDict({
     
     'LightBoxPanel.toggleLightBoxToolBar' : 'View properties',
 
-    'PlotPanel.screenshot'                    : 'Take screenshot',
-    'TimeSeriesPanel.toggleTimeSeriesList'    : 'Time series list',
-    'TimeSeriesPanel.toggleTimeSeriesControl' : 'Time series control', 
-    'HistogramPanel.toggleHistogramList'      : 'Histogram list',
-    'HistogramPanel.toggleHistogramControl'   : 'Histogram control', 
+    'PlotPanel.screenshot'                          : 'Take screenshot',
+    'TimeSeriesPanel.toggleTimeSeriesList'          : 'Time series list',
+    'TimeSeriesPanel.toggleTimeSeriesControl'       : 'Time series control', 
+    'HistogramPanel.toggleHistogramList'            : 'Histogram list',
+    'HistogramPanel.toggleHistogramControl'         : 'Histogram control',
+    'PowerSpectrumPanel.togglePowerSpectrumControl' : 'Power spectrum '
+                                                      'control', 
 
     'OrthoViewProfile.centreCursor' : 'Centre cursor',
     'OrthoViewProfile.resetZoom'    : 'Reset zoom',
@@ -279,6 +283,8 @@ labels = TypeDict({
     'TimeSeriesControlPanel.currentFEATSettings' : 'FEAT settings for '
                                                    'selected overlay ({})',
 
+    'PowerSpectrumControlPanel.psSettings' : 'Power spectrum plot settings',
+
     'TimeSeriesListPanel.featReduced' : 'Reduced against {}',
 
     'FEATModelFitTimeSeries.full' : 'Full model fit',
@@ -398,6 +404,11 @@ properties = TypeDict({
     'HistogramPanel.autoBin'     : 'Automatic histogram binning', 
     'HistogramPanel.showCurrent' : 'Plot histogram for current overlay',
 
+    'PowerSpectrumPanel.showMode'        : 'Power spectra to plot',
+    'PowerSpectrumPanel.plotFrequencies' : 'Show frequencies along x axis ',
+    'PowerSpectrumPanel.plotMelodicICs'  : 'Plot component power spectra for '
+                                           'Melodic images',
+
     'DataSeries.colour'    : 'Colour',
     'DataSeries.alpha'     : 'Line transparency',
     'DataSeries.lineWidth' : 'Line width',
@@ -556,7 +567,14 @@ choices = TypeDict({
                                   'all'     : 'Show the time series '
                                               'for all overlays',
                                   'none'    : 'Only show the time series '
-                                              'in the time series list'}
+                                              'in the time series list'},
+    'PowerSpectrumPanel.showMode' : {'current' : 'Show the power spectrum for '
+                                                 'the currently selected '
+                                                 'overlay',
+                                     'all'     : 'Show the power spectra '
+                                                 'for all overlays',
+                                     'none'    : 'Only show the power spectra '
+                                                 'in the power spectra list'} 
 })
 
 
diff --git a/fsl/fsleyes/controls/powerspectrumcontrolpanel.py b/fsl/fsleyes/controls/powerspectrumcontrolpanel.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e7afb1bcde555b3d0a159697bc96d0d89b932a5
--- /dev/null
+++ b/fsl/fsleyes/controls/powerspectrumcontrolpanel.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+#
+# powerspectrumcontrolpanel.py - The PowerSpectrumControlPanel class.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides the :class:`PowerSpectrumControlPanel` class.
+"""
+
+
+import wx
+
+import                           props
+import pwidgets.widgetlist    as widgetlist
+
+import fsl.fsleyes.panel      as fslpanel
+import fsl.fsleyes.tooltips   as fsltooltips
+import fsl.data.strings       as strings
+import timeseriescontrolpanel as tscontrol
+
+
+class PowerSpectrumControlPanel(fslpanel.FSLEyesPanel):
+    
+    def __init__(self, parent, overlayList, displayCtx, psPanel):
+        
+        fslpanel.FSLEyesPanel.__init__(self, parent, overlayList, displayCtx)
+        
+        self.__psPanel = psPanel
+        self.__widgets = widgetlist.WidgetList(self)
+        self.__sizer   = wx.BoxSizer(wx.VERTICAL)
+        
+        self.SetSizer(self.__sizer)
+        self.__sizer.Add(self.__widgets, flag=wx.EXPAND, proportion=1)
+
+        psProps = ['showMode',
+                   'plotFrequencies',
+                   'plotMelodicICs']
+        
+        self.__widgets.AddGroup(
+            'psSettings', strings.labels[self, 'psSettings'])
+
+        for prop in psProps:
+            
+            kwargs = {}
+            
+            if prop == 'showMode':
+                kwargs['labels'] = strings.choices[psPanel, 'showMode']
+                
+            widget = props.makeWidget(self.__widgets, psPanel, prop, **kwargs)
+            
+            self.__widgets.AddWidget(
+                widget,
+                displayName=strings.properties[psPanel, prop],
+                tooltip=fsltooltips.properties[psPanel, prop],
+                groupName='psSettings')
+
+        self.__widgets.AddGroup(
+            'plotSettings',
+            strings.labels[psPanel, 'plotSettings'])
+            
+        tscontrol.generatePlotPanelWidgets(psPanel,
+                                           self.__widgets,
+                                           'plotSettings') 
diff --git a/fsl/fsleyes/plotting/__init__.py b/fsl/fsleyes/plotting/__init__.py
index 78101338500a40e1c4257931ceed46cc02cbf97a..4090111ce94950fe5f402657f2d7dcf5e6bc6e04 100644
--- a/fsl/fsleyes/plotting/__init__.py
+++ b/fsl/fsleyes/plotting/__init__.py
@@ -12,14 +12,16 @@ for plotting data.
 import dataseries
 import timeseries
 import histogramseries
+import powerspectrumseries
 
-DataSeries               = dataseries.DataSeries
-TimeSeries               = timeseries.TimeSeries
-VoxelTimeSeries          = timeseries.VoxelTimeSeries 
-FEATTimeSeries           = timeseries.FEATTimeSeries
-FEATPartialFitTimeSeries = timeseries.FEATPartialFitTimeSeries
-FEATEVTimeSeries         = timeseries.FEATEVTimeSeries
-FEATResidualTimeSeries   = timeseries.FEATResidualTimeSeries
-FEATModelFitTimeSeries   = timeseries.FEATModelFitTimeSeries
-MelodicTimeSeries        = timeseries.MelodicTimeSeries
-HistogramSeries          = histogramseries.HistogramSeries
+DataSeries               = dataseries         .DataSeries
+TimeSeries               = timeseries         .TimeSeries
+VoxelTimeSeries          = timeseries         .VoxelTimeSeries 
+FEATTimeSeries           = timeseries         .FEATTimeSeries
+FEATPartialFitTimeSeries = timeseries         .FEATPartialFitTimeSeries
+FEATEVTimeSeries         = timeseries         .FEATEVTimeSeries
+FEATResidualTimeSeries   = timeseries         .FEATResidualTimeSeries
+FEATModelFitTimeSeries   = timeseries         .FEATModelFitTimeSeries
+MelodicTimeSeries        = timeseries         .MelodicTimeSeries
+HistogramSeries          = histogramseries    .HistogramSeries
+PowerSpectrumSeries      = powerspectrumseries.PowerSpectrumSeries
diff --git a/fsl/fsleyes/plotting/powerspectrumseries.py b/fsl/fsleyes/plotting/powerspectrumseries.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ce6b4789dc0c3c919bf247a34cae390e780c647
--- /dev/null
+++ b/fsl/fsleyes/plotting/powerspectrumseries.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+#
+# powerspectrumseries.py - Classes used by the PowerSpectrumPanel.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides :class:`.DataSeries` sub-classes which are used
+by the :class:`.PowerSpectrumPanel` for plotting power spectra.
+
+The following classes are provided:
+
+.. autosummary::
+   :nosignature:
+
+   PowerSpectrumSeries
+   VoxelPowerSpectrumSeries
+   MelodicPowerSpectrumSeries
+"""
+
+import logging
+
+import numpy     as np
+import numpy.fft as fft
+
+import props
+
+import dataseries
+
+
+log = logging.getLogger(__name__)
+
+
+class PowerSpectrumSeries(dataseries.DataSeries):
+    """
+    """
+
+    
+    varNorm  = props.Boolean(default=True)
+    """Normalise data to unit variance before fourier transformation. """
+
+
+    def __init__(self, overlay, displayCtx):
+        """
+        """
+        dataseries.DataSeries.__init__(self, overlay)
+        self.displayCtx = displayCtx
+
+        
+    def destroy(self):
+        """
+        """
+        self.displayCtx = None
+        dataseries.DataSeries.destroy(self)
+
+
+    def makeLabel(self):
+        """
+        """
+        display = self.displayCtx.getDisplay(self.overlay)
+        return display.name
+
+
+    def calcPowerSpectrum(self, data):
+        if self.varNorm:
+            data = data - data.mean()
+            data = data / data.std()
+        
+        data = fft.rfft(data)[1:]
+        data = np.power(data.real, 2) + np.power(data.imag, 2)
+
+        return data
+
+
+class VoxelPowerSpectrumSeries(PowerSpectrumSeries):
+
+    def makeLabel(self):
+        """
+        """
+        
+        display = self.displayCtx.getDisplay(self.overlay)
+        opts    = display.getDisplayOpts()
+        coords  = opts.getVoxel()
+
+        if coords is not None:
+            return '{} [{} {} {}]'.format(display.name,
+                                          coords[0],
+                                          coords[1],
+                                          coords[2])
+        else:
+            return '{} [out of bounds]'.format(display.name) 
+
+
+    def getData(self):
+        """
+        """
+        
+        opts  = self.displayCtx.getOpts(self.overlay)
+        voxel = opts.getVoxel()
+
+        if voxel is None:
+            return [], []
+
+        x, y, z = voxel
+
+        ydata = self.overlay.data[x, y, z, :]
+        ydata = self.calcPowerSpectrum(ydata)
+        xdata = np.arange(len(ydata), dtype=np.float32)
+
+        return xdata, ydata
+
+
+class MelodicPowerSpectrumSeries(PowerSpectrumSeries):
+    """
+    """
+
+    def makeLabel(self):
+        """
+        """
+        display   = self.displayCtx.getDisplay(self.overlay)
+        opts      = display.getDisplayOpts()
+        component = opts.volume
+        
+        return '{} [component {}]'.format(display.name, component) 
+
+
+    def getData(self):
+        """
+        """
+
+        opts      = self.displayCtx.getOpts(self.overlay)
+        component = opts.volume
+
+        ydata = self.overlay.getComponentPowerSpectrum(component)
+        xdata = np.arange(len(ydata), dtype=np.float32)
+
+        return xdata, ydata
diff --git a/fsl/fsleyes/tooltips.py b/fsl/fsleyes/tooltips.py
index ca71b292efc7c2602aba80d5d462e256d0a2328e..c70cf46012228d0ddd34488886c6d7a6a242e8a5 100644
--- a/fsl/fsleyes/tooltips.py
+++ b/fsl/fsleyes/tooltips.py
@@ -292,6 +292,23 @@ properties = TypeDict({
     'HistogramPanel.histType'    : 'Show histogram data as raw counts, or '
                                    'as probabilities.',
 
+    'PowerSpectrumPanel.plotFrequencies'  : 'If checked, the x values '
+                                            'are transformed into frequency '
+                                            'values.',
+    'PowerSpectrumPanel.plotMelodicICs'   : 'If checked, the component power '
+                                            'spectra are plotted for Melodic '
+                                            'images. If not checked, Melodic '
+                                            'images are treated as regular 4D '
+                                            'images.',
+    'PowerSpectrumPanel.showMode'         : 'Choose which power spectra to '
+                                            'plot -  you can choose to plot '
+                                            'the power spectrum for the '
+                                            'currently selected overlay, the '
+                                            'power spectra for all compatible '
+                                            'overlays, or just those that '
+                                            'have been added to the power '
+                                            'spectra list.', 
+
     # DataSeries
 
     'DataSeries.colour'    : 'Line colour.',
diff --git a/fsl/fsleyes/views/__init__.py b/fsl/fsleyes/views/__init__.py
index 23f14280190570e7e286fbabd355c26e05f42ab1..015e1538e0986409485d356ed519d6ade29b6d60 100644
--- a/fsl/fsleyes/views/__init__.py
+++ b/fsl/fsleyes/views/__init__.py
@@ -24,6 +24,7 @@ allow dynamic lookup of all :class:`.ViewPanel` sub-classes. The following
    ~fsl.fsleyes.views.lightboxpanel.LightBoxPanel
    ~fsl.fsleyes.views.plotpanel.PlotPanel
    ~fsl.fsleyes.views.timeseriespanel.TimeSeriesPanel
+   ~fsl.fsleyes.views.timeseriespanel.PowerSpectrumPanel
    ~fsl.fsleyes.views.histogrampanel.HistogramPanel
 """
 
@@ -36,17 +37,19 @@ import canvaspanel
 import orthopanel
 import lightboxpanel
 import timeseriespanel
+import powerspectrumpanel
 import histogrampanel
 
 
-FSLEyesPanel    = fslpanel       .FSLEyesPanel
-ViewPanel       = viewpanel      .ViewPanel
-PlotPanel       = plotpanel      .PlotPanel
-CanvasPanel     = canvaspanel    .CanvasPanel
-OrthoPanel      = orthopanel     .OrthoPanel
-LightBoxPanel   = lightboxpanel  .LightBoxPanel
-TimeSeriesPanel = timeseriespanel.TimeSeriesPanel
-HistogramPanel  = histogrampanel .HistogramPanel
+FSLEyesPanel       = fslpanel          .FSLEyesPanel
+ViewPanel          = viewpanel         .ViewPanel
+PlotPanel          = plotpanel         .PlotPanel
+CanvasPanel        = canvaspanel       .CanvasPanel
+OrthoPanel         = orthopanel        .OrthoPanel
+LightBoxPanel      = lightboxpanel     .LightBoxPanel
+TimeSeriesPanel    = timeseriespanel   .TimeSeriesPanel
+PowerSpectrumPanel = powerspectrumpanel.PowerSpectrumPanel
+HistogramPanel     = histogrampanel    .HistogramPanel
 
 
 def listViewPanels():
diff --git a/fsl/fsleyes/views/powerspectrumpanel.py b/fsl/fsleyes/views/powerspectrumpanel.py
new file mode 100644
index 0000000000000000000000000000000000000000..85dc68282ceadea6a109a4353985e949dcd3fc91
--- /dev/null
+++ b/fsl/fsleyes/views/powerspectrumpanel.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+#
+# powerspectrumpanel.py - The PowerSpectrumPanel class.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides the :class:`PowerSpectrumPanel` class, a
+:class:`.ViewPanel` which plots frequency/power spectra.
+"""
+
+
+import logging
+
+import wx
+
+import numpy as np
+
+import props
+
+import                                                   plotpanel
+import fsl.fsleyes.plotting.powerspectrumseries       as psseries
+import fsl.fsleyes.controls.powerspectrumcontrolpanel as pscontrol
+import fsl.fsleyes.colourmaps                         as fslcm
+import fsl.data.image                                 as fslimage
+import fsl.data.melodicimage                          as fslmelimage
+
+
+log = logging.getLogger(__name__)
+
+
+class PowerSpectrumPanel(plotpanel.PlotPanel):
+    """The ``PowerSpectrumPanel`` class is a :class:`.PlotPanel` which plots
+    power spectra of overlay data.
+    """
+
+    
+    plotMelodicICs  = props.Boolean(default=True)
+    """
+    """
+
+
+    plotFrequencies = props.Boolean(default=True)
+    """
+    """
+
+
+    showMode = props.Choice(('current', 'all', 'none'))
+    """
+    """
+
+    
+    def __init__(self, parent, overlayList, displayCtx):
+        """
+        """
+
+        actionz = {
+            'togglePowerSpectrumControl' : lambda *a: self.togglePanel(
+                pscontrol.PowerSpectrumControlPanel,
+                self,
+                location=wx.TOP)
+        }
+        
+        plotpanel.PlotPanel.__init__(self,
+                                     parent,
+                                     overlayList,
+                                     displayCtx,
+                                     actionz=actionz)
+
+        figure = self.getFigure()
+
+        figure.subplots_adjust(
+            top=1.0, bottom=0.0, left=0.0, right=1.0)
+
+        figure.patch.set_visible(False) 
+
+        # A dictionary of
+        # 
+        #   {overlay : PowerSpectrumSeries}
+        #
+        # instances, one for each (compatible)
+        # overlay in the overlay list
+        self.__spectra      = {}
+        self.__refreshProps = {}
+
+        overlayList.addListener('overlays',
+                                self._name,
+                                self.__overlayListChanged)
+        
+        displayCtx .addListener('selectedOverlay',
+                                self._name,
+                                self.__selectedOverlayChanged)
+
+        self.__overlayListChanged()
+
+
+    def destroy(self):
+        self._overlayList.removeListener('overlays',        self._name)
+        self._displayCtx .removeListener('selectedOverlay', self._name)
+
+        plotpanel.PlotPanel.destroy(self)
+        
+
+    def draw(self, *a):
+
+        if self.showMode == 'all':
+            overlays = self._overlayList[:]
+        elif self.showMode == 'current':
+            overlays = [self._displayCtx.getSelectedOverlay()]
+        else:
+            overlays = []
+
+        pss = [self.__spectra.get(o) for o in overlays]
+        pss = [ps for ps in pss if ps is not None]
+
+        self.drawDataSeries(extraSeries=pss,
+                            preproc=self.__prepareSpectrumData)
+
+        
+    def __overlayListChanged(self, *a):
+
+        # Destroy any spectrum series for overlays
+        # that have been removed from the list
+        for ds in list(self.dataSeries):
+            if ds.overlay not in self._overlayList:
+                self.dataSeries.remove(ds)
+                ds.destroy()
+
+        for overlay, ds in list(self.__spectra.items()):
+            if overlay not in self._overlayList:
+                self.__spectra.pop(overlay)
+                ds.destroy()
+
+        # Create a new spectrum series for overlays
+        # which have been added to the list
+        for overlay in self._overlayList:
+            
+            ss = self.__spectra.get(overlay)
+            
+            if ss is None:
+
+                ss, targets, propNames = self.__createSpectrumSeries(overlay)
+
+                if ss is None:
+                    continue
+
+                self.__spectra[     overlay] = ss
+                self.__refreshProps[overlay] = targets, propNames
+
+            ss.addGlobalListener(self._name, self.draw, overwrite=True)
+
+        for targets, propNames in self.__refreshProps.values():
+            for t, p in zip(targets, propNames):
+                t.addListener(p, self._name, self.draw, overwrite=True)
+
+        self.draw()
+
+        
+    def __selectedOverlayChanged(self, *a):
+        self.draw()
+        
+
+    def __prepareSpectrumData(self, ps):
+
+        xdata, ydata = ps.getData()
+
+        if self.plotFrequencies:
+
+            nsamples   = len(ydata)
+            sampleTime = 1
+
+            if isinstance(ps.overlay, fslmelimage.MelodicImage):
+                sampleTime = ps.overlay.tr
+            elif isinstance(ps.overlay, fslimage.Image):
+                sampleTime = ps.overlay.pixdim[3]
+
+            freqStep = 1.0 / (2 * nsamples * sampleTime)
+            xdata    = np.arange(0.0, nsamples * freqStep, freqStep)
+
+        return xdata, ydata
+    
+
+    def __createSpectrumSeries(self, overlay):
+
+        if self.plotMelodicICs and \
+           isinstance(overlay, fslmelimage.MelodicImage):
+            
+            ps        = psseries.MelodicPowerSpectrumSeries(overlay,
+                                                            self._displayCtx)
+            targets   = [self._displayCtx.getOpts(overlay)]
+            propNames = ['volume']
+            
+        elif isinstance(overlay, fslimage.Image):
+            
+            ps        = psseries.VoxelPowerSpectrumSeries(overlay,
+                                                          self._displayCtx)
+            targets   = [self._displayCtx]
+            propNames = ['location']
+            
+        else:
+            return None, [], []
+
+        ps.colour    = fslcm.randomDarkColour()
+        ps.alpha     = 1.0
+        ps.lineWidth = 1
+        ps.lineStyle = '-'
+            
+        return ps, targets, propNames