diff --git a/fsl/data/strings.py b/fsl/data/strings.py
index b60c9d252983b9ac6522d2b00725ea89fd723d5d..e8044fff8e70f35e7bf366168ef5a1deda5f6017 100644
--- a/fsl/data/strings.py
+++ b/fsl/data/strings.py
@@ -198,6 +198,8 @@ titles = TypeDict({
     'TimeSeriesPanel'    : 'Time series',
     'PowerSpectrumPanel' : 'Power spectra',
     'HistogramPanel'     : 'Histogram',
+    'ShellPanel'         : 'Python shell',
+ 
 
     'CanvasPanel.screenshot'          : 'Save screenshot',
     'CanvasPanel.screenshot.notSaved' : 'Save overlay before continuing',
@@ -227,7 +229,6 @@ titles = TypeDict({
     'PowerSpectrumControlPanel' : 'Power spectrum control',
     'ClusterPanel'              : 'Cluster browser',
     'OverlayInfoPanel'          : 'Overlay information',
-    'ShellPanel'                : 'Python shell',
 
     'MelodicClassificationPanel' : 'Melodic IC classification',
 
@@ -277,7 +278,6 @@ actions = TypeDict({
     'CanvasPanel.toggleClusterPanel'        : 'Cluster browser',
     'CanvasPanel.toggleOverlayInfo'         : 'Overlay information',
     'CanvasPanel.toggleClassificationPanel' : 'Melodic IC classification',
-    'CanvasPanel.toggleShell'               : 'Python shell',
     
     'OrthoPanel.toggleOrthoToolBar'     : 'Ortho toolbar',
     'OrthoPanel.toggleEditToolBar'      : 'Edit toolbar',
diff --git a/fsl/fsleyes/controls/__init__.py b/fsl/fsleyes/controls/__init__.py
index d760311ebd7fdcfe1afadeec432dbe5d7316c390..424f2ba338b3a1688efcd83f4aea2bea900174ca 100644
--- a/fsl/fsleyes/controls/__init__.py
+++ b/fsl/fsleyes/controls/__init__.py
@@ -35,7 +35,6 @@ The following control panels currently exist:
    ~fsl.fsleyes.controls.plotcontrolpanel.PlotControlPanel
    ~fsl.fsleyes.controls.plotlistpanel.PlotListPanel
    ~fsl.fsleyes.controls.powerspectrumcontrolpanel.PowerSpectrumControlPanel
-   ~fsl.fsleyes.controls.shellpanel.ShellPanel
    ~fsl.fsleyes.controls.timeseriescontrolpanel.TimeSeriesControlPanel
 """
 
@@ -55,7 +54,6 @@ import overlayinfopanel
 import overlaylistpanel
 import plotlistpanel
 import powerspectrumcontrolpanel
-import shellpanel
 import timeseriescontrolpanel
 
 
@@ -75,5 +73,4 @@ OverlayInfoPanel           = overlayinfopanel.OverlayInfoPanel
 OverlayListPanel           = overlaylistpanel.OverlayListPanel
 PlotListPanel              = plotlistpanel.PlotListPanel
 PowerSpectrumControlPanel  = powerspectrumcontrolpanel.PowerSpectrumControlPanel
-ShellPanel                 = shellpanel.ShellPanel
 TimeSeriesControlPanel     = timeseriescontrolpanel.TimeSeriesControlPanel
diff --git a/fsl/fsleyes/frame.py b/fsl/fsleyes/frame.py
index cc39af989e0ab96db11c8f28eef795f2ae90d790..85ac4b1049c6c6c63840db2e716b60f6a3254fc3 100644
--- a/fsl/fsleyes/frame.py
+++ b/fsl/fsleyes/frame.py
@@ -307,10 +307,15 @@ class FSLEyesFrame(wx.Frame):
         elif issubclass(panelCls, views.CanvasPanel):
             childDC.syncOverlayDisplay = False
 
-        panel = panelCls(
-            self.__mainPanel,
-            self.__overlayList,
-            childDC)
+        if panelCls is views.ShellPanel:
+            panel = panelCls(self.__mainPanel,
+                             self.__overlayList,
+                             childDC,
+                             self)
+        else:
+            panel = panelCls(self.__mainPanel,
+                             self.__overlayList,
+                             childDC)
 
         log.debug('Created new {} ({}) with DisplayContext {}'.format(
             panelCls.__name__,
@@ -349,9 +354,10 @@ class FSLEyesFrame(wx.Frame):
         if panelId > 1:
             width, height = self.GetClientSize().Get()
 
-            # PlotPanels are initially
-            # placed along the bottom
-            if isinstance(panel, views.PlotPanel):
+            # PlotPanels/ShellPanels are
+            # initially placed along the
+            # bottom
+            if isinstance(panel, (views.PlotPanel, views.ShellPanel)):
                 paneInfo.Bottom().BestSize(-1, height / 3)
 
             # Other panels (e.g. CanvasPanels)
@@ -776,7 +782,8 @@ class FSLEyesFrame(wx.Frame):
                       views.LightBoxPanel,
                       views.TimeSeriesPanel,
                       views.PowerSpectrumPanel,
-                      views.HistogramPanel]
+                      views.HistogramPanel,
+                      views.ShellPanel]
         
         for viewPanel in viewPanels:
             viewAction = viewMenu.Append(wx.ID_ANY, strings.titles[viewPanel]) 
diff --git a/fsl/fsleyes/perspectives.py b/fsl/fsleyes/perspectives.py
index bbc0bb076c6383f279d228f1693c0a0f65085fb2..411f135823edb5747c17d90e19748e6787d94701 100644
--- a/fsl/fsleyes/perspectives.py
+++ b/fsl/fsleyes/perspectives.py
@@ -556,7 +556,6 @@ def _addControlPanel(viewPanel, panelType):
         controls.OverlayDisplayToolBar     : {'viewPanel'   : viewPanel},
         controls.PlotListPanel             : {'plotPanel'   : viewPanel},
         controls.PowerSpectrumControlPanel : {'plotPanel'   : viewPanel},
-        controls.ShellPanel                : {'canvasPanel' : viewPanel},
         controls.TimeSeriesControlPanel    : {'plotPanel'   : viewPanel},
     }
 
diff --git a/fsl/fsleyes/views/__init__.py b/fsl/fsleyes/views/__init__.py
index 0b457ffb612284d2fd007229e24ce6ef538f515f..db1fcc9e0719f1e9909c97841086d75ad15b9cbd 100644
--- a/fsl/fsleyes/views/__init__.py
+++ b/fsl/fsleyes/views/__init__.py
@@ -25,6 +25,7 @@ The following :class:`.ViewPanel` sub-classes currently exist:
    ~fsl.fsleyes.views.timeseriespanel.TimeSeriesPanel
    ~fsl.fsleyes.views.powerspectrumpanel.PowerSpectrumPanel
    ~fsl.fsleyes.views.histogrampanel.HistogramPanel
+   ~fsl.fsleyes.views.shellpanel.ShellPanel
 """
 
 
@@ -38,6 +39,7 @@ import lightboxpanel
 import timeseriespanel
 import powerspectrumpanel
 import histogrampanel
+import shellpanel
 
 
 FSLEyesPanel       = fslpanel          .FSLEyesPanel
@@ -49,3 +51,4 @@ LightBoxPanel      = lightboxpanel     .LightBoxPanel
 TimeSeriesPanel    = timeseriespanel   .TimeSeriesPanel
 PowerSpectrumPanel = powerspectrumpanel.PowerSpectrumPanel
 HistogramPanel     = histogrampanel    .HistogramPanel
+ShellPanel         = shellpanel        .ShellPanel
diff --git a/fsl/fsleyes/views/canvaspanel.py b/fsl/fsleyes/views/canvaspanel.py
index bfe545316ba38b9e6ab2818c08f6bd491a20dfb2..606748b6b1cd5f79181c21248d1aa003c5d924fd 100644
--- a/fsl/fsleyes/views/canvaspanel.py
+++ b/fsl/fsleyes/views/canvaspanel.py
@@ -40,7 +40,6 @@ 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
 
@@ -102,7 +101,6 @@ class CanvasPanel(viewpanel.ViewPanel):
        toggleClusterPanel
        toggleLookupTablePanel
        toggleClassificationPanel
-       toggleShell
 
 
     .. _canvaspanel-adding-content:
@@ -403,14 +401,6 @@ class CanvasPanel(viewpanel.ViewPanel):
                          location=wx.RIGHT)
 
 
-    @actions.toggleControlAction(shellpanel.ShellPanel)
-    def toggleShell(self):
-        """Toggles a :class:`.ShellPanel`. See
-        :meth:`.ViewPanel.togglePanel`.
-        """
-        self.togglePanel(shellpanel.ShellPanel, self, location=wx.BOTTOM) 
-
-
     def getSceneOptions(self):
         """Returns the :class:`.SceneOpts` instance used by this
         ``CanvasPanel``.
diff --git a/fsl/fsleyes/views/lightboxpanel.py b/fsl/fsleyes/views/lightboxpanel.py
index 375a86d55fc9089ddfb6cdd7c2879399fbacdebf..f1e4162be046a5af0cba0c15ec86e457a2598bfe 100644
--- a/fsl/fsleyes/views/lightboxpanel.py
+++ b/fsl/fsleyes/views/lightboxpanel.py
@@ -191,8 +191,7 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
                    self.toggleAtlasPanel,
                    self.toggleLookupTablePanel,
                    self.toggleClusterPanel,
-                   self.toggleClassificationPanel,
-                   self.toggleShell]
+                   self.toggleClassificationPanel]
 
         names = [a.__name__ for a in actions]
 
diff --git a/fsl/fsleyes/views/orthopanel.py b/fsl/fsleyes/views/orthopanel.py
index 7ecba10f2c17fe7b12bd62dfaa9fb05b6d517d89..43807e0ece29199777fa093fed266159228331e8 100644
--- a/fsl/fsleyes/views/orthopanel.py
+++ b/fsl/fsleyes/views/orthopanel.py
@@ -282,8 +282,7 @@ class OrthoPanel(canvaspanel.CanvasPanel):
                    self.toggleAtlasPanel,
                    self.toggleLookupTablePanel,
                    self.toggleClusterPanel,
-                   self.toggleClassificationPanel,
-                   self.toggleShell]
+                   self.toggleClassificationPanel]
 
         names = [a.__name__ for a in actions]
 
diff --git a/fsl/fsleyes/controls/shellpanel.py b/fsl/fsleyes/views/shellpanel.py
similarity index 82%
rename from fsl/fsleyes/controls/shellpanel.py
rename to fsl/fsleyes/views/shellpanel.py
index 65087a4a535b52121d2dfa72645f7349a83bf89c..fc145d9fe70016b7f84cc92161174d81783e3976 100644
--- a/fsl/fsleyes/controls/shellpanel.py
+++ b/fsl/fsleyes/views/shellpanel.py
@@ -4,7 +4,7 @@
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
-"""This module provides the :class:`ShellPanel` class, a *FSLeyes control*
+"""This module provides the :class:`ShellPanel` class, a *FSLeyes view*
 which contains an interactive Python shell.
 """
 
@@ -13,11 +13,11 @@ import wx
 
 import wx.py.shell as wxshell
 
-import fsl.fsleyes.panel as fslpanel
+from . import viewpanel
 
 
-class ShellPanel(fslpanel.FSLEyesPanel):
-    """A ``ShellPanel`` is a :class:`.FSLEyesPanel` which contains an
+class ShellPanel(viewpanel.ViewPanel):
+    """A ``ShellPanel`` is a :class:`.ViewPanel` which contains an
     interactive Python shell.
 
     A ``ShellPanel`` allows the user to programmatically interact with the
@@ -26,7 +26,7 @@ class ShellPanel(fslpanel.FSLEyesPanel):
     that owns this ``ShellPanel``.
     """
 
-    def __init__(self, parent, overlayList, displayCtx, canvasPanel):
+    def __init__(self, parent, overlayList, displayCtx, frame):
         """Create a ``ShellPanel``.
 
         :arg parent:      The :mod:`wx` parent object, assumed to be the
@@ -37,15 +37,15 @@ class ShellPanel(fslpanel.FSLEyesPanel):
         :arg displayCtx:  The :class:`.DisplayContext` of the
                           :class:`.CanvasPanel` that owns this ``ShellPanel``.
         
-        :arg canvasPanel: The :class:`.CanvasPanel` that owns this
+        :arg frame:       The :class:`.FSLEyesFrame` that owns this
                           ``ShellPanel``.
         """
-        fslpanel.FSLEyesPanel.__init__(self, parent, overlayList, displayCtx)
+        viewpanel.ViewPanel.__init__(self, parent, overlayList, displayCtx)
 
         lcls = {
             'displayCtx'  : displayCtx,
             'overlayList' : overlayList,
-            'sceneOpts'   : canvasPanel.getSceneOptions(),
+            'frame'       : frame,
             'viewPanel'   : parent,
         }
 
@@ -55,7 +55,7 @@ class ShellPanel(fslpanel.FSLEyesPanel):
                       'Available variables are:\n'
                       '  - overlayList\n' 
                       '  - displayCtx\n'
-                      '  - sceneOpts\n\n'
+                      '  - frame\n'
                       '  - viewPanel\n\n', 
             locals=lcls,
             showInterpIntro=False)
@@ -91,4 +91,4 @@ class ShellPanel(fslpanel.FSLEyesPanel):
         """Must be called when this ``ShellPanel`` is no longer needed.
         Calls the :meth:`.FSLEyesPanel.destroy` method.
         """
-        fslpanel.FSLEyesPanel.destroy(self)
+        viewpanel.ViewPanel.destroy(self)