Index: src/sas/qtgui/Plotter.py
===================================================================
--- src/sas/qtgui/Plotter.py	(revision ef01be48d93733bf0b5ac6ff7ccce2ac92d368b6)
+++ src/sas/qtgui/Plotter.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -1,16 +1,8 @@
-import logging
-
 from PyQt4 import QtGui
 
-# TODO: Replace the qt4agg calls below with qt5 equivalent.
-# Requires some code modifications.
-# https://www.boxcontrol.net/embedding-matplotlib-plot-on-pyqt5-gui.html
-#
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
-from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
 import matplotlib.pyplot as plt
-import matplotlib as mpl
-
-import sas.qtgui.PlotHelper as PlotHelper
+
+from sas.sasgui.plottools import transform
+from sas.sasgui.plottools.convert_units import convert_unit
 from sas.qtgui.PlotterBase import PlotterBase
 
@@ -27,7 +19,6 @@
         """ data setter """
         self._data = value
-        self.label=value.name
-        self.xLabel(xlabel="%s(%s)"%(value._xaxis, value._xunit))
-        self.yLabel(ylabel="%s(%s)"%(value._yaxis, value._yunit))
+        self.xLabel = "%s(%s)"%(value._xaxis, value._xunit)
+        self.yLabel = "%s(%s)"%(value._yaxis, value._yunit)
         self.title(title=value.title)
 
@@ -36,29 +27,174 @@
         Plot self._data
         """
-        # create an axis
+        # Shortcut for an axis
         ax = self.ax
 
         if marker == None:
-            marker = '*'
+            marker = 'o'
 
         if linestyle == None:
             linestyle = '-'
 
-        # plot data with legend
-        ax.plot(self._data.x, self._data.y, marker=marker, linestyle=linestyle, label=self.title)
+        # plot data with title
+        ax.plot(self._data.view.x,
+                self._data.view.y,
+                marker=marker,
+                linestyle=linestyle,
+                label=self._title)
 
         # Now add the legend with some customizations.
         legend = ax.legend(loc='upper right', shadow=True)
 
+        # Current labels for axes
         ax.set_ylabel(self.y_label)
         ax.set_xlabel(self.x_label)
+
         # Title only for regular charts
         if not self.quickplot:
-            ax.set_title(label=self.title)
-
-        ax.set_yscale('log')
-        ax.set_xscale('log')
+            ax.set_title(label=self._title)
+
+        # Include scaling (log vs. linear)
+        ax.set_yscale(self.xscale)
+        ax.set_xscale(self.xscale)
 
         # refresh canvas
         self.canvas.draw()
 
+    def contextMenuQuickPlot(self):
+        """
+        Define context menu and associated actions for the quickplot MPL widget
+        """
+        # Actions
+        self.contextMenu = QtGui.QMenu(self)
+        self.actionSaveImage = self.contextMenu.addAction("Save Image")
+        self.actionPrintImage = self.contextMenu.addAction("Print Image")
+        self.actionCopyToClipboard = self.contextMenu.addAction("Copy to Clipboard")
+        self.contextMenu.addSeparator()
+        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off")
+        self.contextMenu.addSeparator()
+        self.actionChangeScale = self.contextMenu.addAction("Change Scale")
+
+        # Define the callbacks
+        self.actionSaveImage.triggered.connect(self.onImageSave)
+        self.actionPrintImage.triggered.connect(self.onImagePrint)
+        self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy)
+        self.actionToggleGrid.triggered.connect(self.onGridToggle)
+        self.actionChangeScale.triggered.connect(self.onScaleChange)
+
+    def onScaleChange(self):
+        """
+        Show a dialog allowing axes rescaling
+        """
+        if self.properties.exec_() == QtGui.QDialog.Accepted:
+            xLabel, yLabel = self.properties.getValues()
+            self.xyTransform(xLabel, yLabel)
+
+    def xyTransform(self, xLabel="", yLabel=""):
+        """
+        Transforms x and y in View and set the scale
+        """
+        # Clear the plot first
+        plt.cla()
+
+        # Changing the scale might be incompatible with
+        # currently displayed data (for instance, going
+        # from ln to log when all plotted values have
+        # negative natural logs).
+        # Go linear and only change the scale at the end.
+        self._xscale = "linear"
+        self._yscale = "linear"
+        _xscale = 'linear'
+        _yscale = 'linear'
+        # Local data is either 1D or 2D
+        if self.data.id == 'fit':
+            return
+
+        # control axis labels from the panel itself
+        yname, yunits = self.data.get_yaxis()
+        xname, xunits = self.data.get_xaxis()
+
+        # Goes through all possible scales
+        # self.x_label is already wrapped with Latex "$", so using the argument
+
+        # X
+        if xLabel == "x":
+            self.data.transformX(transform.toX, transform.errToX)
+            self.xLabel = "%s(%s)" % (xname, xunits)
+        if xLabel == "x^(2)":
+            self.data.transformX(transform.toX2, transform.errToX2)
+            xunits = convert_unit(2, xunits)
+            self.xLabel = "%s^{2}(%s)" % (xname, xunits)
+        if xLabel == "x^(4)":
+            self.data.transformX(transform.toX4, transform.errToX4)
+            xunits = convert_unit(4, xunits)
+            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
+        if xLabel == "ln(x)":
+            self.data.transformX(transform.toLogX, transform.errToLogX)
+            self.xLabel = "\ln{(%s)}(%s)" % (xname, xunits)
+        if xLabel == "log10(x)":
+            self.data.transformX(transform.toX_pos, transform.errToX_pos)
+            _xscale = 'log'
+            self.xLabel = "%s(%s)" % (xname, xunits)
+        if xLabel == "log10(x^(4))":
+            self.data.transformX(transform.toX4, transform.errToX4)
+            xunits = convert_unit(4, xunits)
+            self.xLabel = "%s^{4}(%s)" % (xname, xunits)
+            _xscale = 'log'
+
+        # Y
+        if yLabel == "ln(y)":
+            self.data.transformY(transform.toLogX, transform.errToLogX)
+            self.yLabel = "\ln{(%s)}(%s)" % (yname, yunits)
+        if yLabel == "y":
+            self.data.transformY(transform.toX, transform.errToX)
+            self.yLabel = "%s(%s)" % (yname, yunits)
+        if yLabel == "log10(y)":
+            self.data.transformY(transform.toX_pos, transform.errToX_pos)
+            _yscale = 'log'
+            self.yLabel = "%s(%s)" % (yname, yunits)
+        if yLabel == "y^(2)":
+            self.data.transformY(transform.toX2, transform.errToX2)
+            yunits = convert_unit(2, yunits)
+            self.yLabel = "%s^{2}(%s)" % (yname, yunits)
+        if yLabel == "1/y":
+            self.data.transformY(transform.toOneOverX, transform.errOneOverX)
+            yunits = convert_unit(-1, yunits)
+            self.yLabel = "1/%s(%s)" % (yname, yunits)
+        if yLabel == "y*x^(2)":
+            self.data.transformY(transform.toYX2, transform.errToYX2)
+            xunits = convert_unit(2, xunits)
+            self.yLabel = "%s \ \ %s^{2}(%s%s)" % (yname, xname, yunits, xunits)
+        if yLabel == "y*x^(4)":
+            self.data.transformY(transform.toYX4, transform.errToYX4)
+            xunits = convert_unit(4, xunits)
+            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
+        if yLabel == "1/sqrt(y)":
+            self.data.transformY(transform.toOneOverSqrtX,
+                                 transform.errOneOverSqrtX)
+            yunits = convert_unit(-0.5, yunits)
+            self.yLabel = "1/\sqrt{%s}(%s)" % (yname, yunits)
+        if yLabel == "ln(y*x)":
+            self.data.transformY(transform.toLogXY, transform.errToLogXY)
+            self.yLabel = "\ln{(%s \ \ %s)}(%s%s)" % (yname, xname, yunits, xunits)
+        if yLabel == "ln(y*x^(2))":
+            self.data.transformY(transform.toLogYX2, transform.errToLogYX2)
+            xunits = convert_unit(2, xunits)
+            self.yLabel = "\ln (%s \ \ %s^{2})(%s%s)" % (yname, xname, yunits, xunits)
+        if yLabel == "ln(y*x^(4))":
+            self.data.transformY(transform.toLogYX4, transform.errToLogYX4)
+            xunits = convert_unit(4, xunits)
+            self.yLabel = "\ln (%s \ \ %s^{4})(%s%s)" % (yname, xname, yunits, xunits)
+        if yLabel == "log10(y*x^(4))":
+            self.data.transformY(transform.toYX4, transform.errToYX4)
+            xunits = convert_unit(4, xunits)
+            _yscale = 'log'
+            self.yLabel = "%s \ \ %s^{4}(%s%s)" % (yname, xname, yunits, xunits)
+
+        # Perform the transformation of data in data1d->View
+        self.data.transformView()
+
+        self.xscale = _xscale
+        self.yscale = _yscale
+
+        # Plot the updated chart
+        self.plot(marker='o', linestyle='')
Index: src/sas/qtgui/Plotter2D.py
===================================================================
--- src/sas/qtgui/Plotter2D.py	(revision ef01be48d93733bf0b5ac6ff7ccce2ac92d368b6)
+++ src/sas/qtgui/Plotter2D.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -1,3 +1,2 @@
-import logging
 import copy
 import numpy
@@ -6,16 +5,7 @@
 from PyQt4 import QtGui
 
-# TODO: Replace the qt4agg calls below with qt5 equivalent.
-# Requires some code modifications.
-# https://www.boxcontrol.net/embedding-matplotlib-plot-on-pyqt5-gui.html
-#
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
-from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
-import matplotlib.pyplot as plt
-
 DEFAULT_CMAP = pylab.cm.jet
 
 import sas.qtgui.PlotUtilities as PlotUtilities
-import sas.qtgui.PlotHelper as PlotHelper
 from sas.qtgui.PlotterBase import PlotterBase
 
@@ -41,6 +31,7 @@
         self.zmax=data.zmax
         self.label=data.name
-        self.xLabel(xlabel="%s(%s)"%(data._xaxis, data._xunit))
-        self.yLabel(ylabel="%s(%s)"%(data._yaxis, data._yunit))
+        self.dimension=2
+        self.xLabel="%s(%s)"%(data._xaxis, data._xunit)
+        self.yLabel="%s(%s)"%(data._yaxis, data._yunit)
         self.title(title=data.title)
 
@@ -57,5 +48,5 @@
         # Title only for regular charts
         if not self.quickplot:
-            ax.set_title(label=self.title)
+            ax.set_title(label=self._title)
 
         # Re-adjust colorbar
@@ -75,6 +66,167 @@
         cb = self.figure.colorbar(im, cax=cbax)
         cb.update_bruteforce(im)
-        cb.set_label('$' + self._scale + '$')
+        cb.set_label('$' + self.scale + '$')
 
         # Schedule the draw for the next time the event loop is idle.
         self.canvas.draw_idle()
+
+    def contextMenuQuickPlot(self):
+        """
+        Define context menu and associated actions for the quickplot MPL widget
+        """
+        # Actions
+        self.contextMenu = QtGui.QMenu(self)
+        self.actionSaveImage = self.contextMenu.addAction("Save Image")
+        self.actionPrintImage = self.contextMenu.addAction("Print Image")
+        self.actionCopyToClipboard = self.contextMenu.addAction("Copy to Clipboard")
+        self.contextMenu.addSeparator()
+        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off")
+        self.contextMenu.addSeparator()
+        self.actionChangeScale = self.contextMenu.addAction("Toggle Linear/Log Scale")
+
+        # Define the callbacks
+        self.actionSaveImage.triggered.connect(self.onImageSave)
+        self.actionPrintImage.triggered.connect(self.onImagePrint)
+        self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy)
+        self.actionToggleGrid.triggered.connect(self.onGridToggle)
+        self.actionChangeScale.triggered.connect(self.onToggleScale)
+
+    def onToggleScale(self, event):
+        """
+        Toggle axis and replot image
+
+        """
+        zmin_2D_temp = self.zmin
+        zmax_2D_temp = self.zmax
+        if self.scale == 'log_{10}':
+            self.scale = 'linear'
+            if not self.zmin is None:
+                zmin_2D_temp = math.pow(10, self.zmin)
+            if not self.zmax is None:
+                zmax_2D_temp = math.pow(10, self.zmax)
+        else:
+            self.scale = 'log_{10}'
+            if not self.zmin is None:
+                # min log value: no log(negative)
+                if self.zmin <= 0:
+                    zmin_2D_temp = -32
+                else:
+                    zmin_2D_temp = math.log10(self.zmin)
+            if not self.zmax is None:
+                zmax_2D_temp = math.log10(self.zmax)
+
+        self.image(data=self.data.data, qx_data=self.qx_data,
+                   qy_data=self.qy_data, xmin=self.xmin,
+                   xmax=self.xmax,
+                   ymin=self.ymin, ymax=self.ymax,
+                   cmap=self.cmap, zmin=zmin_2D_temp,
+                   zmax=zmax_2D_temp)
+
+
+    def image(self, data, qx_data, qy_data, xmin, xmax, ymin, ymax,
+              zmin, zmax, color=0, symbol=0, markersize=0,
+              label='data2D', cmap=DEFAULT_CMAP):
+        """
+        Render the current data
+
+        """
+        #self.data = data
+        self.qx_data = qx_data
+        self.qy_data = qy_data
+        self.xmin = xmin
+        self.xmax = xmax
+        self.ymin = ymin
+        self.ymax = ymax
+        self.zmin = zmin
+        self.zmax = zmax
+        #c = self.color(color)
+        # If we don't have any data, skip.
+        if data == None:
+            return
+        if data.ndim == 1:
+            #output = self._build_matrix()
+            output = PlotUtilities.build_matrix(data, self.qx_data, self.qy_data)
+        else:
+            output = copy.deepcopy(data)
+
+        zmin_temp = self.zmin
+        # check scale
+        if self.scale == 'log_{10}':
+            try:
+                if  self.zmin <= 0  and len(output[output > 0]) > 0:
+                    zmin_temp = self.zmin_2D
+                    output[output > 0] = numpy.log10(output[output > 0])
+                    #In log scale Negative values are not correct in general
+                    #output[output<=0] = math.log(numpy.min(output[output>0]))
+                elif self.zmin <= 0:
+                    zmin_temp = self.zmin
+                    output[output > 0] = numpy.zeros(len(output))
+                    output[output <= 0] = -32
+                else:
+                    zmin_temp = self.zmin
+                    output[output > 0] = numpy.log10(output[output > 0])
+                    #In log scale Negative values are not correct in general
+                    #output[output<=0] = math.log(numpy.min(output[output>0]))
+            except:
+                #Too many problems in 2D plot with scale
+                output[output > 0] = numpy.log10(output[output > 0])
+                pass
+
+        self.cmap = cmap
+        if self.dimension != 3:
+            #Re-adjust colorbar
+            self.figure.subplots_adjust(left=0.2, right=.8, bottom=.2)
+
+            im = self.ax.imshow(output, interpolation='nearest',
+                                origin='lower',
+                                vmin=zmin_temp, vmax=self.zmax,
+                                cmap=self.cmap,
+                                extent=(self.xmin, self.xmax,
+                                        self.ymin, self.ymax))
+
+            cbax = self.figure.add_axes([0.84, 0.2, 0.02, 0.7])
+        else:
+            # clear the previous 2D from memory
+            # mpl is not clf, so we do
+            self.figure.clear()
+
+            self.figure.subplots_adjust(left=0.1, right=.8, bottom=.1)
+
+            X = self.x_bins[0:-1]
+            Y = self.y_bins[0:-1]
+            X, Y = numpy.meshgrid(X, Y)
+
+            try:
+                # mpl >= 1.0.0
+                ax = self.figure.gca(projection='3d')
+                #ax.disable_mouse_rotation()
+                cbax = self.figure.add_axes([0.84, 0.1, 0.02, 0.8])
+                if len(X) > 60:
+                    ax.disable_mouse_rotation()
+            except:
+                # mpl < 1.0.0
+                try:
+                    from mpl_toolkits.mplot3d import Axes3D
+                except:
+                    logging.error("PlotPanel could not import Axes3D")
+                self.figure.clear()
+                ax = Axes3D(self.figure)
+                if len(X) > 60:
+                    ax.cla()
+                cbax = None
+            self.figure.canvas.resizing = False
+            im = ax.plot_surface(X, Y, output, rstride=1, cstride=1, cmap=cmap,
+                                 linewidth=0, antialiased=False)
+            self.set_axis_off()
+
+        if cbax == None:
+            ax.set_frame_on(False)
+            cb = self.figure.colorbar(im, shrink=0.8, aspect=20)
+        else:
+            cb = self.figure.colorbar(im, cax=cbax)
+        cb.update_bruteforce(im)
+        cb.set_label('$' + self.scale + '$')
+        if self.dimension != 3:
+            self.figure.canvas.draw_idle()
+        else:
+            self.figure.canvas.draw()
Index: src/sas/qtgui/PlotterBase.py
===================================================================
--- src/sas/qtgui/PlotterBase.py	(revision ef01be48d93733bf0b5ac6ff7ccce2ac92d368b6)
+++ src/sas/qtgui/PlotterBase.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -1,9 +1,5 @@
-import logging
-import copy
-import numpy
 import pylab
 
 from PyQt4 import QtGui
-from PyQt4 import QtCore
 
 # TODO: Replace the qt4agg calls below with qt5 equivalent.
@@ -13,5 +9,4 @@
 from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
 from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
-from matplotlib.backend_bases import NavigationToolbar2
 
 import matplotlib.pyplot as plt
@@ -45,15 +40,21 @@
         # set the layout
         layout = QtGui.QVBoxLayout()
+        layout.setMargin(0)
         layout.addWidget(self.canvas)
 
         # defaults
         self.current_plot = 111
-        self._data = []
+        self._data = [] # Original 1D/2D object
+        self._xscale = 'log'
+        self._yscale = 'log'
         self.qx_data = []
         self.qy_data = []
         self.color=0
         self.symbol=0
+        self.dimension=1
         self.grid_on = False
         self.scale = 'linear'
+        self.x_label = "log10(x)"
+        self.y_label = "log10(y)"
 
         # default color map
@@ -64,7 +65,10 @@
 
         if not quickplot:
+            # set the layout
             layout.addWidget(self.toolbar)
             # Notify the helper
             PlotHelper.addPlot(self)
+            # Add the context menu
+            self.contextMenu()
             # Notify the listeners
             self.parent.communicator.activeGraphsSignal.emit(PlotHelper.currentPlots())
@@ -80,19 +84,31 @@
     @data.setter
     def data(self, data=None):
-        """ data setter """
-        pass
+        """ virtual data setter """
+        raise ImportError("Data setter must be implemented in derived class.")
 
     def title(self, title=""):
         """ title setter """
-        self.title = title
-
-    def id(self, id=""):
-        """ id setter """
-        self.id = id
-
+        self._title = title
+
+    #def id(self, id=""):
+    #    """ id setter """
+    #    self.id = id
+
+    @property
+    def xLabel(self, xlabel=""):
+        """ x-label setter """
+        return self.x_label
+
+    @xLabel.setter
     def xLabel(self, xlabel=""):
         """ x-label setter """
         self.x_label = r'$%s$'% xlabel
 
+    @property
+    def yLabel(self, ylabel=""):
+        """ y-label setter """
+        return self.y_label
+
+    @yLabel.setter
     def yLabel(self, ylabel=""):
         """ y-label setter """
@@ -102,24 +118,24 @@
     def yscale(self):
         """ Y-axis scale getter """
-        return self.yscale
+        return self._yscale
 
     @yscale.setter
     def yscale(self, scale='linear'):
         """ Y-axis scale setter """
-        self.subplot.set_yscale(scale, nonposy='clip')
-        self.yscale = scale
+        self.ax.set_yscale(scale, nonposy='clip')
+        self._yscale = scale
 
     @property
     def xscale(self):
         """ X-axis scale getter """
-        return self.xscale
+        return self._xscale
 
     @xscale.setter
     def xscale(self, scale='linear'):
         """ X-axis scale setter """
-        self.subplot.set_xscale(scale)
-        self.xscale = scale
-
-    def contextMenuQuickPlot(self):
+        self.ax.set_xscale(scale)
+        self._xscale = scale
+
+    def contextMenu(self):
         """
         Define context menu and associated actions for the MPL widget
@@ -131,7 +147,4 @@
         self.actionCopyToClipboard = self.contextMenu.addAction("Copy to Clipboard")
         self.contextMenu.addSeparator()
-        self.actionToggleGrid = self.contextMenu.addAction("Toggle Grid On/Off")
-        self.contextMenu.addSeparator()
-        self.actionChangeScale = self.contextMenu.addAction("Change Scale")
 
         # Define the callbacks
@@ -139,6 +152,10 @@
         self.actionPrintImage.triggered.connect(self.onImagePrint)
         self.actionCopyToClipboard.triggered.connect(self.onClipboardCopy)
-        self.actionToggleGrid.triggered.connect(self.onGridToggle)
-        self.actionChangeScale.triggered.connect(self.onScaleChange)
+
+    def contextMenuQuickPlot(self):
+        """
+        Define context menu and associated actions for the quickplot MPL widget
+        """
+        raise ImportError("Context menu method must be implemented in derived class.")
 
     def contextMenuEvent(self, event):
@@ -217,147 +234,2 @@
         self.ax.grid(self.grid_on)
         self.canvas.draw_idle()
-
-    def onScaleChange(self):
-        """
-        Show a dialog allowing axes rescaling
-        """
-        if self.properties.exec_() == QtGui.QDialog.Accepted:
-            xLabel, yLabel = self.properties.getValues()
-            #self.xyTransform(xLabel, yLabel)
-
-    def xyTransform(self, xLabel="", yLabel=""):
-        """
-        Transforms x and y in View and set the scale
-        """
-        # The logic should be in the right order
-        self.ly = None
-        self.q_ctrl = None
-        # Changing the scale might be incompatible with
-        # currently displayed data (for instance, going
-        # from ln to log when all plotted values have
-        # negative natural logs).
-        # Go linear and only change the scale at the end.
-        self.set_xscale("linear")
-        self.set_yscale("linear")
-        _xscale = 'linear'
-        _yscale = 'linear'
-        # Local data is either 1D or 2D
-        #for item in list:
-        #if item.id == 'fit':
-        #    continue
-        item.setLabel(self.xLabel, self.yLabel)
-        # control axis labels from the panel itself
-        yname, yunits = item.get_yaxis()
-        if self.yaxis_label != None:
-            yname = self.yaxis_label
-            yunits = self.yaxis_unit
-        else:
-            self.yaxis_label = yname
-            self.yaxis_unit = yunits
-        xname, xunits = item.get_xaxis()
-        if self.xaxis_label != None:
-            xname = self.xaxis_label
-            xunits = self.xaxis_unit
-        else:
-            self.xaxis_label = xname
-            self.xaxis_unit = xunits
-        # Goes through all possible scales
-        if self.xLabel == "x":
-            item.transformX(transform.toX, transform.errToX)
-            self.graph._xaxis_transformed("%s" % xname, "%s" % xunits)
-        if self.xLabel == "x^(2)":
-            item.transformX(transform.toX2, transform.errToX2)
-            xunits = convert_unit(2, xunits)
-            self.graph._xaxis_transformed("%s^{2}" % xname, "%s" % xunits)
-        if self.xLabel == "x^(4)":
-            item.transformX(transform.toX4, transform.errToX4)
-            xunits = convert_unit(4, xunits)
-            self.graph._xaxis_transformed("%s^{4}" % xname, "%s" % xunits)
-        if self.xLabel == "ln(x)":
-            item.transformX(transform.toLogX, transform.errToLogX)
-            self.graph._xaxis_transformed("\ln{(%s)}" % xname, "%s" % xunits)
-        if self.xLabel == "log10(x)":
-            item.transformX(transform.toX_pos, transform.errToX_pos)
-            _xscale = 'log'
-            self.graph._xaxis_transformed("%s" % xname, "%s" % xunits)
-        if self.xLabel == "log10(x^(4))":
-            item.transformX(transform.toX4, transform.errToX4)
-            xunits = convert_unit(4, xunits)
-            self.graph._xaxis_transformed("%s^{4}" % xname, "%s" % xunits)
-            _xscale = 'log'
-        if self.yLabel == "ln(y)":
-            item.transformY(transform.toLogX, transform.errToLogX)
-            self.graph._yaxis_transformed("\ln{(%s)}" % yname, "%s" % yunits)
-        if self.yLabel == "y":
-            item.transformY(transform.toX, transform.errToX)
-            self.graph._yaxis_transformed("%s" % yname, "%s" % yunits)
-        if self.yLabel == "log10(y)":
-            item.transformY(transform.toX_pos, transform.errToX_pos)
-            _yscale = 'log'
-            self.graph._yaxis_transformed("%s" % yname, "%s" % yunits)
-        if self.yLabel == "y^(2)":
-            item.transformY(transform.toX2, transform.errToX2)
-            yunits = convert_unit(2, yunits)
-            self.graph._yaxis_transformed("%s^{2}" % yname, "%s" % yunits)
-        if self.yLabel == "1/y":
-            item.transformY(transform.toOneOverX, transform.errOneOverX)
-            yunits = convert_unit(-1, yunits)
-            self.graph._yaxis_transformed("1/%s" % yname, "%s" % yunits)
-        if self.yLabel == "y*x^(2)":
-            item.transformY(transform.toYX2, transform.errToYX2)
-            xunits = convert_unit(2, self.xaxis_unit)
-            self.graph._yaxis_transformed("%s \ \ %s^{2}" % (yname, xname),
-                                            "%s%s" % (yunits, xunits))
-        if self.yLabel == "y*x^(4)":
-            item.transformY(transform.toYX4, transform.errToYX4)
-            xunits = convert_unit(4, self.xaxis_unit)
-            self.graph._yaxis_transformed("%s \ \ %s^{4}" % (yname, xname),
-                                            "%s%s" % (yunits, xunits))
-        if self.yLabel == "1/sqrt(y)":
-            item.transformY(transform.toOneOverSqrtX,
-                            transform.errOneOverSqrtX)
-            yunits = convert_unit(-0.5, yunits)
-            self.graph._yaxis_transformed("1/\sqrt{%s}" % yname,
-                                            "%s" % yunits)
-        if self.yLabel == "ln(y*x)":
-            item.transformY(transform.toLogXY, transform.errToLogXY)
-            self.graph._yaxis_transformed("\ln{(%s \ \ %s)}" % (yname, xname),
-                                            "%s%s" % (yunits, self.xaxis_unit))
-        if self.yLabel == "ln(y*x^(2))":
-            item.transformY(transform.toLogYX2, transform.errToLogYX2)
-            xunits = convert_unit(2, self.xaxis_unit)
-            self.graph._yaxis_transformed("\ln (%s \ \ %s^{2})" % (yname, xname),
-                                            "%s%s" % (yunits, xunits))
-        if self.yLabel == "ln(y*x^(4))":
-            item.transformY(transform.toLogYX4, transform.errToLogYX4)
-            xunits = convert_unit(4, self.xaxis_unit)
-            self.graph._yaxis_transformed("\ln (%s \ \ %s^{4})" % (yname, xname),
-                                            "%s%s" % (yunits, xunits))
-        if self.yLabel == "log10(y*x^(4))":
-            item.transformY(transform.toYX4, transform.errToYX4)
-            xunits = convert_unit(4, self.xaxis_unit)
-            _yscale = 'log'
-            self.graph._yaxis_transformed("%s \ \ %s^{4}" % (yname, xname),
-                                            "%s%s" % (yunits, xunits))
-            item.transformView()
-
-        # set new label and units
-        yname = self.graph.prop["ylabel"]
-        yunits = ''
-        xname = self.graph.prop["xlabel"]
-        xunits = ''
-
-        self.resetFitView()
-        self.prevXtrans = self.xLabel
-        self.prevYtrans = self.yLabel
-        self.graph.render(self)
-        self.set_xscale(_xscale)
-        self.set_yscale(_yscale)
-
-        self.xaxis(xname, xunits, self.xaxis_font,
-                   self.xaxis_color, self.xaxis_tick)
-        self.yaxis(yname, yunits, self.yaxis_font,
-                   self.yaxis_color, self.yaxis_tick)
-        self.subplot.texts = self.textList
-
-        self.canvas.draw_idle()
Index: src/sas/qtgui/ScaleProperties.py
===================================================================
--- src/sas/qtgui/ScaleProperties.py	(revision ef01be48d93733bf0b5ac6ff7ccce2ac92d368b6)
+++ src/sas/qtgui/ScaleProperties.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -1,6 +1,2 @@
-# global
-#import sys
-#import os
-#from PyQt4 import QtCore
 from PyQt4 import QtGui
 
@@ -36,4 +32,6 @@
         # Connect combobox index change to a custom method
         self.cbView.currentIndexChanged.connect(self.viewIndexChanged)
+        self.cbX.currentIndexChanged.connect(self.xyIndexChanged)
+        self.cbY.currentIndexChanged.connect(self.xyIndexChanged)
 
     def getValues(self):
@@ -48,4 +46,19 @@
         """
         if index > 0:
+            # Disable signals so xyIndexChanged() doesn't get called
+            self.cbX.blockSignals(True)
+            self.cbY.blockSignals(True)
+
+            # Update the sub-controls
             self.cbX.setCurrentIndex(view_to_xy[view_values[index]][0])
             self.cbY.setCurrentIndex(view_to_xy[view_values[index]][1])
+            # Re-enable the signals
+
+            self.cbX.blockSignals(False)
+            self.cbY.blockSignals(False)
+
+    def xyIndexChanged(self, index):
+        """
+        Update View label based on the "X" and "Y" index
+        """
+        self.cbView.setCurrentIndex(0)
Index: src/sas/qtgui/UnitTesting/DataExplorerTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/DataExplorerTest.py	(revision 31c5b583d8c577c4ed72be87d22d34ec2ed50c04)
+++ src/sas/qtgui/UnitTesting/DataExplorerTest.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -506,5 +506,5 @@
         self.assertTrue(self.form.manager.add_data.called)
 
-    def testNewPlot(self):
+    def testNewPlot1D(self):
         """
         Creating new plots from Data1D/2D
@@ -521,4 +521,37 @@
         # get Data1D
         p_file="cyl_400_20.txt"
+        output_object = loader.load(p_file)
+        new_data = [manager.create_gui_data(output_object, p_file)]
+
+        # Mask retrieval of the data
+        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
+
+        # Mask plotting
+        self.form.parent.workspace = MagicMock()
+
+        # Call the plotting method
+        self.form.newPlot()
+
+        # The plot was registered
+        self.assertEqual(len(PlotHelper.currentPlots()), 1)
+
+        self.assertTrue(self.form.cbgraph.isEnabled())
+        self.assertTrue(self.form.cmdAppend.isEnabled())
+
+    def testNewPlot2D(self):
+        """
+        Creating new plots from Data1D/2D
+        """
+        loader = Loader()
+        manager = DataManager()
+        PlotHelper.clear()
+        self.form.enableGraphCombo(None)
+
+        # Make sure the controls are disabled
+        self.assertFalse(self.form.cbgraph.isEnabled())
+        self.assertFalse(self.form.cmdAppend.isEnabled())
+
+        # get Data2D
+        p_file="Dec07031.ASC"
         output_object = loader.load(p_file)
         new_data = [manager.create_gui_data(output_object, p_file)]
Index: src/sas/qtgui/UnitTesting/PlotterTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/PlotterTest.py	(revision f721030e66e61dc6279aa8e024da03b25f8e0d42)
+++ src/sas/qtgui/UnitTesting/PlotterTest.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -0,0 +1,115 @@
+import sys
+import unittest
+
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from mock import MagicMock
+
+####### TEMP
+import LocalSetup
+#######
+from sas.sasgui.guiframe.dataFitting import Data1D
+from sas.sasgui.guiframe.dataFitting import Data2D
+from UnitTesting.TestUtils import QtSignalSpy
+
+# Tested module
+import sas.qtgui.Plotter as Plotter
+
+app = QtGui.QApplication(sys.argv)
+
+class PlotterTest(unittest.TestCase):
+    '''Test the Plotter 1D class'''
+    def setUp(self):
+        '''create'''
+        self.plotter = Plotter.Plotter(None, quickplot=True)
+        self.data = Data1D(x=[1.0, 2.0, 3.0],
+                           y=[10.0, 11.0, 12.0],
+                           dx=[0.1, 0.2, 0.3],
+                           dy=[0.1, 0.2, 0.3])
+        self.data.title="Test data"
+        self.data.id = 1
+
+    def tearDown(self):
+        '''destroy'''
+        self.plotter = None
+
+    def testDataProperty(self):
+        """ Adding data """
+        self.plotter.data = self.data
+
+        self.assertEqual(self.plotter.data, self.data)
+        self.assertEqual(self.plotter._title, self.data.title)
+        self.assertEqual(self.plotter.xLabel, "$()$")
+        self.assertEqual(self.plotter.yLabel, "$()$")
+
+    def testPlot(self):
+        """ Look at the plotting """
+        self.plotter.data = self.data
+        self.plotter.show()
+        FigureCanvas.draw = MagicMock()
+
+        self.plotter.plot()
+
+        self.assertTrue(FigureCanvas.draw.called)
+
+    def testContextMenuQuickPlot(self):
+        """ Test the right click menu """
+        actions = self.plotter.contextMenu.actions()
+        self.assertEqual(len(actions), 7)
+
+        # Trigger Save Image and make sure the method is called
+        self.assertEqual(actions[0].text(), "Save Image")
+        self.plotter.toolbar.save_figure = MagicMock()
+        actions[0].trigger()
+        self.assertTrue(self.plotter.toolbar.save_figure.called)
+
+        # Trigger Print Image and make sure the method is called
+        self.assertEqual(actions[1].text(), "Print Image")
+        QtGui.QPrintDialog.exec_ = MagicMock(return_value=QtGui.QDialog.Rejected)
+        actions[1].trigger()
+        self.assertTrue(QtGui.QPrintDialog.exec_.called)
+
+        # Trigger Copy to Clipboard and make sure the method is called
+        self.assertEqual(actions[2].text(), "Copy to Clipboard")
+
+        # Spy on cliboard's dataChanged() signal
+        self.clipboard_called = False
+        def done():
+            self.clipboard_called = True
+        QtCore.QObject.connect(app.clipboard(), QtCore.SIGNAL("dataChanged()"), done)
+        actions[2].trigger()
+        QtGui.qApp.processEvents()
+        # Make sure clipboard got updated.
+        self.assertTrue(self.clipboard_called)
+
+        # Trigger Toggle Grid and make sure the method is called
+        self.assertEqual(actions[4].text(), "Toggle Grid On/Off")
+        self.plotter.ax.grid = MagicMock()
+        actions[4].trigger()
+        self.assertTrue(self.plotter.ax.grid.called)
+
+        # Trigger Change Scale and make sure the method is called
+        self.assertEqual(actions[6].text(), "Change Scale")
+        self.plotter.properties.exec_ = MagicMock(return_value=QtGui.QDialog.Rejected)
+        actions[6].trigger()
+        self.assertTrue(self.plotter.properties.exec_.called)
+
+    def testXYTransform(self):
+        """ Assure the unit/legend transformation is correct"""
+        self.plotter.data = self.data
+
+        self.plotter.xyTransform(xLabel="ln(x)", yLabel="ln(y)")
+        self.assertEqual(self.plotter.ax.get_xlabel(), "$\\ln{()}()$")
+        self.assertEqual(self.plotter.ax.get_ylabel(), "$\\ln{()}()$")
+
+        self.plotter.xyTransform(xLabel="ln(x)", yLabel="ln(y)")
+        self.assertEqual(self.plotter.ax.get_xlabel(), "$\\ln{()}()$")
+        self.assertEqual(self.plotter.ax.get_ylabel(), "$\\ln{()}()$")
+
+        self.plotter.xyTransform(xLabel="x^(2)", yLabel="1/sqrt(y)")
+        self.assertEqual(self.plotter.ax.get_xlabel(), "$^{2}(()^{2})$")
+        self.assertEqual(self.plotter.ax.get_ylabel(), "$1/\\sqrt{}(()^{-0.5})$")
+
+if __name__ == "__main__":
+    unittest.main()
Index: src/sas/qtgui/UnitTesting/ScalePropertiesTest.py
===================================================================
--- src/sas/qtgui/UnitTesting/ScalePropertiesTest.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
+++ src/sas/qtgui/UnitTesting/ScalePropertiesTest.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -0,0 +1,60 @@
+import sys
+import unittest
+
+from PyQt4 import QtGui
+
+# set up import paths
+import path_prepare
+
+# Local
+from ScaleProperties import ScaleProperties
+
+app = QtGui.QApplication(sys.argv)
+
+class ScalePropertiesTest(unittest.TestCase):
+    '''Test the ScaleProperties'''
+    def setUp(self):
+        '''Create the ScaleProperties'''
+
+        self.widget = ScaleProperties(None)
+
+    def tearDown(self):
+        '''Destroy the GUI'''
+        self.widget.close()
+        self.widget = None
+
+    def testDefaults(self):
+        '''Test the GUI in its default state'''
+        self.assertIsInstance(self.widget, QtGui.QDialog)
+        self.assertEqual(self.widget.windowTitle(), "Scale Properties")
+        self.assertEqual(self.widget.cbX.count(), 6)
+        self.assertEqual(self.widget.cbY.count(), 12)
+        self.assertEqual(self.widget.cbView.count(), 6)
+        
+    def testGetValues(self):
+        '''Test the values returned'''
+        self.assertEqual(self.widget.getValues(), ("x", "y"))
+        self.widget.cbX.setCurrentIndex(2)
+        self.widget.cbY.setCurrentIndex(4)
+        self.assertEqual(self.widget.getValues(), ("x^(4)", "y*x^(2)"))
+
+    def testSettingView(self):
+        '''Test various settings of view'''
+        self.widget.cbView.setCurrentIndex(1)
+        self.assertEqual(self.widget.getValues(), ("x", "y"))
+        self.widget.cbView.setCurrentIndex(5)
+        self.assertEqual(self.widget.getValues(), ("x", "y*x^(2)"))
+
+        # Assure the View combobox resets on the x index changes
+        self.assertNotEqual(self.widget.cbView.currentIndex(), 0)
+        self.widget.cbX.setCurrentIndex(2)
+        self.assertEqual(self.widget.cbView.currentIndex(), 0)
+
+        # Same for Y
+        self.widget.cbView.setCurrentIndex(6)
+        self.assertNotEqual(self.widget.cbView.currentIndex(), 0)
+        self.widget.cbY.setCurrentIndex(2)
+        self.assertEqual(self.widget.cbView.currentIndex(), 0)
+      
+if __name__ == "__main__":
+    unittest.main()
Index: src/sas/sasgui/plottools/config.py
===================================================================
--- src/sas/sasgui/plottools/config.py	(revision d7bb5267934b5676c90b1655346a3793a8022965)
+++ src/sas/sasgui/plottools/config.py	(revision 6d05e1d115a38b7805a83cb480014af70b58ef75)
@@ -35,12 +35,12 @@
 # Sort out matplotlib version
 import matplotlib
-try:
-    import pkg_resources
-    pkg_resources.require("matplotlib>=" + plot_version)
-except:
-    from distutils.version import LooseVersion as Version
-    if Version(matplotlib.__version__) < Version(plot_version):
-        msg = "Matplotlib version must be %s or newer" % (plot_version, )
-        raise ImportError(msg)
+#try:
+#    import pkg_resources
+#    pkg_resources.require("matplotlib>=" + plot_version)
+#except:
+#    from distutils.version import LooseVersion as Version
+#    if Version(matplotlib.__version__) < Version(plot_version):
+#        msg = "Matplotlib version must be %s or newer" % (plot_version, )
+#        raise ImportError(msg)
 
 # Sort out matplotlib backend
@@ -51,5 +51,6 @@
 elif matplotlib.get_backend() != plot_backend:
     # if a backend has already been selected, make sure it is the correct one.
-    raise ImportError("Matplotlib not using backend " + plot_backend)
+    #raise ImportError("Matplotlib not using backend " + plot_backend)
+    pass
 
 # set global plot style
