Index: setup.py
===================================================================
--- setup.py	(revision 3010f6810ba153e9cdad01da8b9b794f692d60b4)
+++ setup.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -392,7 +392,8 @@
 package_dir["sas.qtgui.Plotting.Slicers"] = os.path.join(
     "src", "sas", "qtgui", "Plotting", "Slicers")
-packages.extend(["sas.qtgui.Plotting", "sas.qtgui.Plotting.UI", "sas.qtgui.Plotting.Slicers"])
-
-
+package_dir["sas.qtgui.Plotting.Masks"] = os.path.join(
+    "src", "sas", "qtgui", "Plotting", "Masks")
+packages.extend(["sas.qtgui.Plotting", "sas.qtgui.Plotting.UI",
+                 "sas.qtgui.Plotting.Slicers", "sas.qtgui.Plotting.Masks"])
 
 # # Last of the sas.models
Index: src/sas/qtgui/MainWindow/DataExplorer.py
===================================================================
--- src/sas/qtgui/MainWindow/DataExplorer.py	(revision aed053275d5f293f1f6495be4c78e4b18fc52b41)
+++ src/sas/qtgui/MainWindow/DataExplorer.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -91,4 +91,5 @@
         self.communicator.activeGraphName.connect(self.updatePlotName)
         self.communicator.plotUpdateSignal.connect(self.updatePlot)
+        self.communicator.maskEditorSignal.connect(self.showEditDataMask)
 
         self.cbgraph.editTextChanged.connect(self.enableGraphCombo)
@@ -990,14 +991,15 @@
         new_plot.show()
 
-    def showEditDataMask(self):
+    def showEditDataMask(self, data=None):
         """
         Mask Editor for 2D plots
         """
-        index = self.current_view.selectedIndexes()[0]
-        proxy = self.current_view.model()
-        model = proxy.sourceModel()
-        model_item = model.itemFromIndex(proxy.mapToSource(index))
-
-        data = GuiUtils.dataFromItem(model_item)
+        if data is None or not isinstance(data, Data2D):
+            index = self.current_view.selectedIndexes()[0]
+            proxy = self.current_view.model()
+            model = proxy.sourceModel()
+            model_item = model.itemFromIndex(proxy.mapToSource(index))
+
+            data = GuiUtils.dataFromItem(model_item)
 
         mask_editor = MaskEditor(self, data)
Index: src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision 9a7c81c9d7824d6d653a3572a51e2647fcbced2c)
+++ src/sas/qtgui/Perspectives/Fitting/FittingWidget.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -384,5 +384,5 @@
         self.chk2DView.setVisible(False)
         self.chkMagnetism.setEnabled(self.is2D)
-        self.tabFitting.setTabEnabled(TAB_MAGNETISM, self.is2D)
+        self.tabFitting.setTabEnabled(TAB_MAGNETISM, self.chkMagnetism.isChecked())
         # Combo box or label for file name"
         if self.is_batch_fitting:
@@ -510,4 +510,5 @@
 
         # Signals from separate tabs asking for replot
+        self.options_widget.plot_signal.connect(self.onOptionsUpdate)
         self.options_widget.plot_signal.connect(self.onOptionsUpdate)
 
Index: src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py
===================================================================
--- src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py	(revision 9a7c81c9d7824d6d653a3572a51e2647fcbced2c)
+++ src/sas/qtgui/Perspectives/Fitting/OptionsWidget.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -127,4 +127,5 @@
         Callback for running the mask editor
         """
+        self.parent.communicate.maskEditorSignal.emit(self.logic.data)
         pass
 
Index: src/sas/qtgui/Plotting/MaskEditor.py
===================================================================
--- src/sas/qtgui/Plotting/MaskEditor.py	(revision 4992ff2626be19df7de9e5dfc0078b96bf47a75e)
+++ src/sas/qtgui/Plotting/MaskEditor.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -1,4 +1,6 @@
-from PyQt5 import QtCore
-from PyQt5 import QtGui
+from functools import partial
+import copy
+import numpy as np
+
 from PyQt5 import QtWidgets
 
@@ -10,18 +12,30 @@
 from sas.qtgui.Plotting.Plotter2D import Plotter2DWidget
 
+from sas.qtgui.Plotting.Masks.SectorMask import SectorMask
+from sas.qtgui.Plotting.Masks.BoxMask import BoxMask
+from sas.qtgui.Plotting.Masks.CircularMask import CircularMask
+
+
 class MaskEditor(QtWidgets.QDialog, Ui_MaskEditorUI):
     def __init__(self, parent=None, data=None):
         super(MaskEditor, self).__init__()
 
-        assert(isinstance(data, Data2D))
+        assert isinstance(data, Data2D)
 
         self.setupUi(self)
 
         self.data = data
+        self.parent = parent
         filename = data.name
+
+        self.current_slicer = None
+        self.slicer_mask = None
+
         self.setWindowTitle("Mask Editor for %s" % filename)
 
         self.plotter = Plotter2DWidget(self, manager=parent, quickplot=True)
         self.plotter.data = self.data
+        self.slicer_z = 0
+        self.default_mask = copy.deepcopy(data.mask)
 
         layout = QtWidgets.QHBoxLayout()
@@ -31,3 +45,188 @@
 
         self.plotter.plot()
-
+        self.subplot = self.plotter.ax
+
+        # update mask
+        self.updateMask(self.default_mask)
+
+        self.initializeSignals()
+
+    def initializeSignals(self):
+        """
+        Attach slots to signals from radio boxes
+        """
+        self.rbWings.toggled.connect(partial(self.onMask, slicer=SectorMask, inside=True))
+        self.rbCircularDisk.toggled.connect(partial(self.onMask, slicer=CircularMask, inside=True))
+        self.rbRectangularDisk.toggled.connect(partial(self.onMask, slicer=BoxMask, inside=True))
+        self.rbDoubleWingWindow.toggled.connect(partial(self.onMask, slicer=SectorMask, inside=False))
+        self.rbCircularWindow.toggled.connect(partial(self.onMask, slicer=CircularMask, inside=False))
+        self.rbRectangularWindow.toggled.connect(partial(self.onMask, slicer=BoxMask, inside=False))
+
+        # Button groups defined so we can uncheck all buttons programmatically
+        self.buttonGroup = QtWidgets.QButtonGroup()
+        self.buttonGroup.addButton(self.rbWings)
+        self.buttonGroup.addButton(self.rbCircularDisk)
+        self.buttonGroup.addButton(self.rbRectangularDisk)
+        self.buttonGroup.addButton(self.rbDoubleWingWindow)
+        self.buttonGroup.addButton(self.rbCircularWindow)
+        self.buttonGroup.addButton(self.rbRectangularWindow)
+
+        # Push buttons
+        self.cmdAdd.clicked.connect(self.onAdd)
+        self.cmdReset.clicked.connect(self.onReset)
+        self.cmdClear.clicked.connect(self.onClear)
+
+    def emptyRadioButtons(self):
+        """
+        Uncheck all buttons without them firing signals causing unnecessary slicer updates
+        """
+        self.buttonGroup.setExclusive(False)
+        self.rbWings.blockSignals(True)
+        self.rbWings.setChecked(False)
+        self.rbWings.blockSignals(False)
+
+        self.rbCircularDisk.blockSignals(True)
+        self.rbCircularDisk.setChecked(False)
+        self.rbCircularDisk.blockSignals(False)
+
+        self.rbRectangularDisk.blockSignals(True)
+        self.rbRectangularDisk.setChecked(False)
+        self.rbRectangularDisk.blockSignals(False)
+
+        self.rbDoubleWingWindow.blockSignals(True)
+        self.rbDoubleWingWindow.setChecked(False)
+        self.rbDoubleWingWindow.blockSignals(False)
+
+        self.rbCircularWindow.blockSignals(True)
+        self.rbCircularWindow.setChecked(False)
+        self.rbCircularWindow.blockSignals(False)
+
+        self.rbRectangularWindow.blockSignals(True)
+        self.rbRectangularWindow.setChecked(False)
+        self.rbRectangularWindow.blockSignals(False)
+        self.buttonGroup.setExclusive(True)
+
+    def setSlicer(self, slicer):
+        """
+        Clear the previous slicer and create a new one.
+        slicer: slicer class to create
+        """
+        # Clear current slicer
+        if self.current_slicer is not None:
+            self.current_slicer.clear()
+        # Create a new slicer
+        self.slicer_z += 1
+        self.current_slicer = slicer(self, self.ax, zorder=self.slicer_z)
+        self.ax.set_ylim(self.data.ymin, self.data.ymax)
+        self.ax.set_xlim(self.data.xmin, self.data.xmax)
+        # Draw slicer
+        self.figure.canvas.draw()
+        self.current_slicer.update()
+
+    def onMask(self, slicer=None, inside=True):
+        """
+        Clear the previous mask and create a new one.
+        """
+        self.clearSlicer()
+        # modifying data in-place
+        self.slicer_z += 1
+
+        self.current_slicer = slicer(self.plotter, self.plotter.ax, zorder=self.slicer_z, side=inside)
+
+        self.plotter.ax.set_ylim(self.data.ymin, self.data.ymax)
+        self.plotter.ax.set_xlim(self.data.xmin, self.data.xmax)
+
+        self.plotter.canvas.draw()
+
+        self.slicer_mask = self.current_slicer.update()
+
+    def update(self):
+        """
+        Redraw the canvas
+        """
+        self.plotter.draw()
+
+    def onAdd(self):
+        """
+        Generate required mask and modify underlying DATA
+        """
+        if self.current_slicer is None:
+            return
+        data = Data2D()
+        data = self.data
+        self.slicer_mask = self.current_slicer.update()
+        data.mask = self.data.mask & self.slicer_mask
+        self.updateMask(data.mask)
+        self.emptyRadioButtons()
+
+    def onClear(self):
+        """
+        Remove the current mask(s)
+        """
+        self.slicer_z += 1
+        self.clearSlicer()
+        self.current_slicer = BoxMask(self.plotter, self.plotter.ax,
+                                      zorder=self.slicer_z, side=True)
+        self.plotter.ax.set_ylim(self.data.ymin, self.data.ymax)
+        self.plotter.ax.set_xlim(self.data.xmin, self.data.xmax)
+
+        self.data.mask = copy.deepcopy(self.default_mask)
+        # update mask plot
+        self.updateMask(self.data.mask)
+        self.emptyRadioButtons()
+
+    def onReset(self):
+        """
+        Removes all the masks from data
+        """
+        self.slicer_z += 1
+        self.clearSlicer()
+        self.current_slicer = BoxMask(self.plotter, self.plotter.ax,
+                                      zorder=self.slicer_z, side=True)
+        self.plotter.ax.set_ylim(self.data.ymin, self.data.ymax)
+        self.plotter.ax.set_xlim(self.data.xmin, self.data.xmax)
+        mask = np.ones(len(self.data.mask), dtype=bool)
+        self.data.mask = mask
+        # update mask plot
+        self.updateMask(mask)
+        self.emptyRadioButtons()
+
+    def clearSlicer(self):
+        """
+        Clear the slicer on the plot
+        """
+        if self.current_slicer is None:
+            return
+
+        self.current_slicer.clear()
+        self.plotter.draw()
+        self.current_slicer = None
+
+    def updateMask(self, mask):
+        """
+        Respond to changes in masking
+        """
+        # the case of liitle numbers of True points
+        if len(mask[mask]) < 10 and self.data is not None:
+            self.data.mask = copy.deepcopy(self.mask)
+        else:
+            self.mask = mask
+        # make temperary data to plot
+        temp_mask = np.zeros(len(mask))
+        temp_data = copy.deepcopy(self.data)
+        # temp_data default is None
+        # This method is to distinguish between masked point and data point = 0.
+        temp_mask = temp_mask / temp_mask
+        temp_mask[mask] = temp_data.data[mask]
+
+        temp_data.data[mask == False] = temp_mask[mask == False]
+
+        if self.current_slicer is not None:
+            self.current_slicer.clear()
+            self.current_slicer = None
+
+        # modify imshow data
+        self.plotter.plot(data=temp_data)
+        self.plotter.draw()
+
+        self.subplot = self.plotter.ax
Index: src/sas/qtgui/Plotting/Masks/BoxMask.py
===================================================================
--- src/sas/qtgui/Plotting/Masks/BoxMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
+++ src/sas/qtgui/Plotting/Masks/BoxMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -0,0 +1,228 @@
+import numpy as np
+
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.BoxSum import PointInteractor
+from sas.qtgui.Plotting.Slicers.BoxSum import VerticalDoubleLine
+from sas.qtgui.Plotting.Slicers.BoxSum import HorizontalDoubleLine
+
+
+class BoxMask(BaseInteractor):
+    """
+    BoxMask Class: determine 2 rectangular area to find the pixel of
+    a Data inside of box.
+
+    Uses PointerInteractor , VerticalDoubleLine,HorizontalDoubleLine.
+
+    :param zorder:  Artists with lower zorder values are drawn first.
+    :param x_min: the minimum value of the x coordinate
+    :param x_max: the maximum value of the x coordinate
+    :param y_min: the minimum value of the y coordinate
+    :param y_max: the maximum value of the y coordinate
+
+    """
+    def __init__(self, base, axes, color='black', zorder=3, side=None,
+                 x_min=0.008, x_max=0.008, y_min=0.0025, y_max=0.0025):
+        """
+        """
+        BaseInteractor.__init__(self, base, axes, color=color)
+        # list of Boxmask markers
+        self.markers = []
+        self.axes = axes
+        self.mask = None
+        self.is_inside = side
+        # connect the artist for the motion
+        self.connect = self.base.connect
+        # when qmax is reached the selected line is reset
+        self.qmax = min(self.base.data.xmax, self.base.data.xmin)
+        # Define the box limits
+        self.xmin = -1 * 0.5 * min(np.fabs(self.base.data.xmax),
+                                   np.fabs(self.base.data.xmin))
+        self.ymin = -1 * 0.5 * min(np.fabs(self.base.data.xmax),
+                                   np.fabs(self.base.data.xmin))
+        self.xmax = 0.5 * min(np.fabs(self.base.data.xmax),
+                              np.fabs(self.base.data.xmin))
+        self.ymax = 0.5 * min(np.fabs(self.base.data.xmax),
+                              np.fabs(self.base.data.xmin))
+        # center of the box
+        self.center_x = 0.0002
+        self.center_y = 0.0003
+        # Number of points on the plot
+        self.nbins = 20
+        # Define initial result the summation
+        self.count = 0
+        self.error = 0
+        self.data = self.base.data
+        # Flag to determine if the current figure has moved
+        # set to False == no motion , set to True== motion
+        self.has_move = False
+        # Create Box edges
+        self.horizontal_lines = HorizontalDoubleLine(self,
+                                                     self.axes,
+                                                     color='blue',
+                                                     zorder=zorder,
+                                                     y=self.ymax,
+                                                     x=self.xmax,
+                                                     center_x=self.center_x,
+                                                     center_y=self.center_y)
+        self.horizontal_lines.qmax = self.qmax
+
+        self.vertical_lines = VerticalDoubleLine(self,
+                                                 self.axes,
+                                                 color='grey',
+                                                 zorder=zorder,
+                                                 y=self.ymax,
+                                                 x=self.xmax,
+                                                 center_x=self.center_x,
+                                                 center_y=self.center_y)
+        self.vertical_lines.qmax = self.qmax
+
+        self.center = PointInteractor(self,
+                                      self.axes, color='grey',
+                                      zorder=zorder,
+                                      center_x=self.center_x,
+                                      center_y=self.center_y)
+        # Save the name of the slicer panel associate with this slicer
+        self.panel_name = ""
+        # Update and post slicer parameters
+        self.update()
+        self._post_data()
+
+    def clear(self):
+        """
+        Clear the slicer and all connected events related to this slicer
+        """
+        self.clear_markers()
+        self.horizontal_lines.clear()
+        self.vertical_lines.clear()
+        self.center.clear()
+        self.base.connect.clearall()
+
+    def update(self):
+        """
+        Respond to changes in the model by recalculating the profiles and
+        resetting the widgets.
+        """
+        # check if the center point has moved and update the figure accordingly
+        if self.center.has_move:
+            self.center.update()
+            self.horizontal_lines.update(center=self.center)
+            self.vertical_lines.update(center=self.center)
+        # # check if the horizontal lines have moved and update
+        # the figure accordingly
+        if self.horizontal_lines.has_move:
+            self.horizontal_lines.update()
+            self.vertical_lines.update(y1=self.horizontal_lines.y1,
+                                       y2=self.horizontal_lines.y2,
+                                       height=self.horizontal_lines.half_height)
+        # # check if the vertical lines have moved and update
+        # the figure accordingly
+        if self.vertical_lines.has_move:
+            self.vertical_lines.update()
+            self.horizontal_lines.update(x1=self.vertical_lines.x1,
+                                         x2=self.vertical_lines.x2,
+                                         width=self.vertical_lines.half_width)
+        # if self.is_inside is not None:
+        out = self._post_data()
+        return out
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.horizontal_lines.save(ev)
+        self.vertical_lines.save(ev)
+        self.center.save(ev)
+
+    def _post_data(self):
+        """
+        Get the limits of the boxsum and compute the sum of the pixel
+        contained in that region and the error on that sum
+        """
+        from sas.sascalc.dataloader.manipulations import Boxcut
+        # # Data 2D for which the pixel will be summed
+        data = self.base.data
+        mask = data.mask
+        # # the region of the summation
+        x_min = self.horizontal_lines.x2
+        x_max = self.horizontal_lines.x1
+        y_min = self.vertical_lines.y2
+        y_max = self.vertical_lines.y1
+        mask = Boxcut(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
+
+        if self.is_inside:
+            out = (mask(data) == False)
+        else:
+            out = (mask(data))
+        # self.base.data.mask=out
+        self.mask = mask
+        return out
+
+    def moveend(self, ev):
+        """
+        After a dragging motion this function is called to compute
+        the error and the sum of pixel of a given data 2D
+        """
+        self._post_data()
+
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.horizontal_lines.restore()
+        self.vertical_lines.restore()
+        self.center.restore()
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        pass
+
+    def set_cursor(self, x, y):
+        pass
+
+    def get_params(self):
+        """
+        Store a copy of values of parameters of the slicer into a dictionary.
+
+        :return params: the dictionary created
+        """
+        params = {}
+        params["Width"] = np.fabs(self.vertical_lines.half_width) * 2
+        params["Height"] = np.fabs(self.horizontal_lines.half_height) * 2
+        params["center_x"] = self.center.x
+        params["center_y"] = self.center.y
+        return params
+
+    def get_mask(self):
+        """
+        return mask as a result of boxcut
+        """
+        mask = self.mask
+        return mask
+
+    def set_params(self, params):
+        """
+        Receive a dictionary and reset the slicer with values contained
+        in the values of the dictionary.
+
+        :param params: a dictionary containing name of slicer parameters and
+           values the user assigned to the slicer.
+        """
+        x_max = np.fabs(params["Width"]) / 2
+        y_max = np.fabs(params["Height"]) / 2
+
+        self.center_x = params["center_x"]
+        self.center_y = params["center_y"]
+        # update the slicer given values of params
+        self.center.update(center_x=self.center_x, center_y=self.center_y)
+        self.horizontal_lines.update(center=self.center, width=x_max, height=y_max)
+        self.vertical_lines.update(center=self.center, width=x_max, height=y_max)
+        # compute the new error and sum given values of params
+        self._post_data()
+
+    def draw(self):
+        self.base.update()
+
+
Index: src/sas/qtgui/Plotting/Masks/CircularMask.py
===================================================================
--- src/sas/qtgui/Plotting/Masks/CircularMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
+++ src/sas/qtgui/Plotting/Masks/CircularMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -0,0 +1,158 @@
+import numpy
+
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.AnnulusSlicer import RingInteractor
+
+class CircularMask(BaseInteractor):
+    """
+     Draw a ring Given a radius
+    """
+    def __init__(self, base, axes, color='grey', zorder=3, side=None):
+        """
+        :param: the color of the line that defined the ring
+        :param r: the radius of the ring
+        :param sign: the direction of motion the the marker
+        """
+        BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self.base = base
+        self.is_inside = side
+        self.qmax = min(numpy.fabs(self.base.data.xmax),
+                        numpy.fabs(self.base.data.xmin))  # must be positive
+        self.connect = self.base.connect
+
+        # Cursor position of Rings (Left(-1) or Right(1))
+        self.xmaxd = self.base.data.xmax
+        self.xmind = self.base.data.xmin
+
+        if (self.xmaxd + self.xmind) > 0:
+            self.sign = 1
+        else:
+            self.sign = -1
+        # Inner circle
+        self.outer_circle = RingInteractor(self, self.axes, 'blue',
+                                           zorder=zorder + 1, r=self.qmax / 1.8,
+                                           sign=self.sign)
+        self.outer_circle.qmax = self.qmax * 1.2
+        self.update()
+        self._post_data()
+
+    def set_layer(self, n):
+        """
+        Allow adding plot to the same panel
+        :param n: the number of layer
+        """
+        self.layernum = n
+        self.update()
+
+    def clear(self):
+        """
+        Clear the slicer and all connected events related to this slicer
+        """
+        self.clear_markers()
+        self.outer_circle.clear()
+
+        self.base.connect.clearall()
+
+    def update(self):
+        """
+        Respond to changes in the model by recalculating the profiles and
+        resetting the widgets.
+        """
+        # Update locations
+        self.outer_circle.update()
+        self._post_data()
+        out = self._post_data()
+        return out
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.outer_circle.save(ev)
+
+    def _post_data(self):
+        """
+        Uses annulus parameters to plot averaged data into 1D data.
+
+        :param nbins: the number of points to plot
+
+        """
+        # Data to average
+        data = self.base.data
+
+        # If we have no data, just return
+        if data is None:
+            return
+        mask = data.mask
+        from sas.sascalc.dataloader.manipulations import Ringcut
+
+        rmin = 0
+        rmax = numpy.fabs(self.outer_circle.get_radius())
+
+        # Create the data1D Q average of data2D
+        mask = Ringcut(r_min=rmin, r_max=rmax)
+
+        if self.is_inside:
+            out = (mask(data) == False)
+        else:
+            out = (mask(data))
+        return out
+
+
+    def moveend(self, ev):
+        """
+        Called when any dragging motion ends.
+        Post an event (type =SlicerParameterEvent)
+        to plotter 2D with a copy  slicer parameters
+        Call  _post_data method
+        """
+        #self.base.thaw_axes()
+        # create a 1D data plot
+        self._post_data()
+
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.outer_circle.restore()
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        pass
+
+    def set_cursor(self, x, y):
+        pass
+
+    def getParams(self):
+        """
+        Store a copy of values of parameters of the slicer into a dictionary.
+
+        :return params: the dictionary created
+
+        """
+        params = {}
+        params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x)
+        return params
+
+    def setParams(self, params):
+        """
+        Receive a dictionary and reset the slicer with values contained
+        in the values of the dictionary.
+
+        :param params: a dictionary containing name of slicer parameters and
+            values the user assigned to the slicer.
+        """
+        outer = numpy.fabs(params["outer_radius"])
+        # Update the picture
+        self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y)
+        # Post the data given the nbins entered by the user
+        self._post_data()
+
+    def draw(self):
+        self.base.update()
+
Index: src/sas/qtgui/Plotting/Masks/SectorMask.py
===================================================================
--- src/sas/qtgui/Plotting/Masks/SectorMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
+++ src/sas/qtgui/Plotting/Masks/SectorMask.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -0,0 +1,197 @@
+"""
+    Sector mask interactor
+"""
+import numpy as np
+
+from qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
+from qtgui.Plotting.Slicers.SectorSlicer import SideInteractor
+from qtgui.Plotting.Slicers.SectorSlicer import LineInteractor
+
+class SectorMask(BaseInteractor):
+    """
+    Draw a sector slicer.Allow to find the data 2D inside of the sector lines
+    """
+    def __init__(self, base, axes, color='gray', zorder=3, side=False):
+        """
+        """
+        BaseInteractor.__init__(self, base, axes, color=color)
+        # Class initialization
+        self.markers = []
+        self.axes = axes
+        self.is_inside = side
+        # connect the plot to event
+        self.connect = self.base.connect
+
+        ## compute qmax limit to reset the graph
+        x = np.power(max(self.base.data.xmax,
+                         np.fabs(self.base.data.xmin)), 2)
+        y = np.power(max(self.base.data.ymax,
+                         np.fabs(self.base.data.ymin)), 2)
+        self.qmax = np.sqrt(x + y)
+        ## Number of points on the plot
+        self.nbins = 20
+        ## Angle of the middle line
+        self.theta2 = np.pi / 3
+        ## Absolute value of the Angle between the middle line and any side line
+        self.phi = np.pi / 12
+
+        ## Middle line
+        self.main_line = LineInteractor(self, self.base.ax, color='blue',
+                                        zorder=zorder, r=self.qmax, theta=self.theta2)
+        self.main_line.qmax = self.qmax
+        ## Right Side line
+        self.right_line = SideInteractor(self, self.base.ax, color='gray',
+                                         zorder=zorder, r=self.qmax, phi=-1 * self.phi,
+                                         theta2=self.theta2)
+        self.right_line.qmax = self.qmax
+        ## Left Side line
+        self.left_line = SideInteractor(self, self.base.ax, color='gray',
+                                        zorder=zorder, r=self.qmax, phi=self.phi,
+                                        theta2=self.theta2)
+        self.left_line.qmax = self.qmax
+        ## draw the sector
+        self.update()
+        self._post_data()
+
+    def clear(self):
+        """
+        Clear the slicer and all connected events related to this slicer
+        """
+        self.clear_markers()
+        self.main_line.clear()
+        self.left_line.clear()
+        self.right_line.clear()
+        self.base.connect.clearall()
+
+    def update(self):
+        """
+        Respond to changes in the model by recalculating the profiles and
+        resetting the widgets.
+        """
+        # Update locations
+        ## Check if the middle line was dragged and
+        #update the picture accordingly
+        if self.main_line.has_move:
+            self.main_line.update()
+            self.right_line.update(delta=-self.left_line.phi / 2,
+                                   mline=self.main_line.theta)
+            self.left_line.update(delta=self.left_line.phi / 2,
+                                  mline=self.main_line.theta)
+        ## Check if the left side has moved and update the slicer accordingly
+        if self.left_line.has_move:
+            self.main_line.update()
+            self.left_line.update(phi=None, delta=None, mline=self.main_line,
+                                  side=True, left=True)
+            self.right_line.update(phi=self.left_line.phi, delta=None,
+                                   mline=self.main_line, side=True,
+                                   left=False, right=True)
+        ## Check if the right side line has moved and
+        #update the slicer accordingly
+        if self.right_line.has_move:
+            self.main_line.update()
+            self.right_line.update(phi=None, delta=None, mline=self.main_line,
+                                   side=True, left=False, right=True)
+            self.left_line.update(phi=self.right_line.phi, delta=None,
+                                  mline=self.main_line, side=True, left=False)
+        #if self.is_inside is not None:
+        out = self._post_data()
+        return out
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.main_line.save(ev)
+        self.right_line.save(ev)
+        self.left_line.save(ev)
+
+    def _post_data(self):
+        """
+        compute sector averaging of data into data1D
+        """
+        ## get the data to average
+        data = self.base.data
+        # If we have no data, just return
+        if data is None:
+            return
+        ## Averaging
+        from sas.sascalc.dataloader.manipulations import Sectorcut
+        phimin = -self.left_line.phi + self.main_line.theta
+        phimax = self.left_line.phi + self.main_line.theta
+
+        mask = Sectorcut(phi_min=phimin, phi_max=phimax)
+        if self.is_inside:
+            out = (mask(data) == False)
+        else:
+            out = (mask(data))
+        return out
+
+    def moveend(self, ev):
+        """
+        Called a dragging motion ends.Get slicer event
+        """
+        ## Send slicer paramers to plotter2D
+        self._post_data()
+
+    def restore(self):
+        """
+        Restore the roughness for this layer.
+        """
+        self.main_line.restore()
+        self.left_line.restore()
+        self.right_line.restore()
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        pass
+
+    def set_cursor(self, x, y):
+        pass
+
+    def get_params(self):
+        """
+        Store a copy of values of parameters of the slicer into a dictionary.
+
+        :return params: the dictionary created
+
+        """
+        params = {}
+        ## Always make sure that the left and the right line are at phi
+        ## angle of the middle line
+        if np.fabs(self.left_line.phi) != np.fabs(self.right_line.phi):
+            msg = "Phi left and phi right are "
+            msg += "different %f, %f" % (self.left_line.phi,
+                                         self.right_line.phi)
+            raise (ValueError, msg)
+        params["Phi"] = self.main_line.theta
+        params["Delta_Phi"] = np.fabs(self.left_line.phi)
+        return params
+
+    def set_params(self, params):
+        """
+        Receive a dictionary and reset the slicer with values contained
+        in the values of the dictionary.
+
+        :param params: a dictionary containing name of slicer parameters and
+            values the user assigned to the slicer.
+        """
+        main = params["Phi"]
+        phi = np.fabs(params["Delta_Phi"])
+
+        self.main_line.theta = main
+        ## Reset the slicer parameters
+        self.main_line.update()
+        self.right_line.update(phi=phi, delta=None, mline=self.main_line,
+                               side=True, right=True)
+        self.left_line.update(phi=phi, delta=None,
+                              mline=self.main_line, side=True)
+        ## post the new corresponding data
+        self._post_data()
+
+    def draw(self):
+        """
+        """
+        self.base.update()
Index: src/sas/qtgui/Plotting/Masks/__init__.py
===================================================================
--- src/sas/qtgui/Plotting/Masks/__init__.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
+++ src/sas/qtgui/Plotting/Masks/__init__.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -0,0 +1,1 @@
+
Index: src/sas/qtgui/Plotting/Plotter2D.py
===================================================================
--- src/sas/qtgui/Plotting/Plotter2D.py	(revision d6b8a1dfaf6521ae4a9054d5195def2810d6d8bc)
+++ src/sas/qtgui/Plotting/Plotter2D.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -61,4 +61,5 @@
         self.vmin = None
         self.vmax = None
+        self.im = None
 
         self.manager = manager
@@ -439,6 +440,8 @@
                 zmin_temp = self.vmin
                 zmax_temp = self.vmax
-
-            im = self.ax.imshow(output, interpolation='nearest',
+            if self.im is not None:
+                self.im.set_data(output)
+            else:
+                self.im = self.ax.imshow(output, interpolation='nearest',
                                 # origin='lower',
                                 vmin=zmin_temp, vmax=zmax_temp,
@@ -459,9 +462,9 @@
             if cbax is None:
                 ax.set_frame_on(False)
-                cb = self.figure.colorbar(im, shrink=0.8, aspect=20)
+                cb = self.figure.colorbar(self.im, shrink=0.8, aspect=20)
             else:
-                cb = self.figure.colorbar(im, cax=cbax)
-
-            cb.update_bruteforce(im)
+                cb = self.figure.colorbar(self.im, cax=cbax)
+
+            cb.update_bruteforce(self.im)
             cb.set_label('$' + self.scale + '$')
 
Index: src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py	(revision 4992ff2626be19df7de9e5dfc0078b96bf47a75e)
+++ src/sas/qtgui/Plotting/Slicers/AnnulusSlicer.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -382,154 +382,3 @@
         self.set_cursor(x, self._inner_mouse_y)
 
-class CircularMask(BaseInteractor):
-    """
-     Draw a ring Given a radius
-    """
-    def __init__(self, base, axes, color='grey', zorder=3, side=None):
-        """
-        :param: the color of the line that defined the ring
-        :param r: the radius of the ring
-        :param sign: the direction of motion the the marker
-        """
-        BaseInteractor.__init__(self, base, axes, color=color)
-        self.markers = []
-        self.axes = axes
-        self.base = base
-        self.is_inside = side
-        self.qmax = min(numpy.fabs(self.base.data.xmax),
-                        numpy.fabs(self.base.data.xmin))  # must be positive
-        self.connect = self.base.connect
-
-        # Cursor position of Rings (Left(-1) or Right(1))
-        self.xmaxd = self.base.data.xmax
-        self.xmind = self.base.data.xmin
-
-        if (self.xmaxd + self.xmind) > 0:
-            self.sign = 1
-        else:
-            self.sign = -1
-        # Inner circle
-        self.outer_circle = RingInteractor(self, self.axes, 'blue',
-                                           zorder=zorder + 1, r=self.qmax / 1.8,
-                                           sign=self.sign)
-        self.outer_circle.qmax = self.qmax * 1.2
-        self.update()
-        self._post_data()
-
-    def set_layer(self, n):
-        """
-        Allow adding plot to the same panel
-        :param n: the number of layer
-        """
-        self.layernum = n
-        self.update()
-
-    def clear(self):
-        """
-        Clear the slicer and all connected events related to this slicer
-        """
-        self.clear_markers()
-        self.outer_circle.clear()
-        self.base.connect.clearall()
-
-    def update(self):
-        """
-        Respond to changes in the model by recalculating the profiles and
-        resetting the widgets.
-        """
-        # Update locations
-        self.outer_circle.update()
-        self._post_data()
-        out = self._post_data()
-        return out
-
-    def save(self, ev):
-        """
-        Remember the roughness for this layer and the next so that we
-        can restore on Esc.
-        """
-        self.outer_circle.save(ev)
-
-    def _post_data(self):
-        """
-        Uses annulus parameters to plot averaged data into 1D data.
-
-        :param nbins: the number of points to plot
-
-        """
-        # Data to average
-        data = self.base.data
-
-        # If we have no data, just return
-        if data is None:
-            return
-        mask = data.mask
-        from sas.sascalc.dataloader.manipulations import Ringcut
-
-        rmin = 0
-        rmax = numpy.fabs(self.outer_circle.get_radius())
-
-        # Create the data1D Q average of data2D
-        mask = Ringcut(r_min=rmin, r_max=rmax)
-
-        if self.is_inside:
-            out = (mask(data) == False)
-        else:
-            out = (mask(data))
-        return out
-
-
-    def moveend(self, ev):
-        """
-        Called when any dragging motion ends.
-        Post an event (type =SlicerParameterEvent)
-        to plotter 2D with a copy  slicer parameters
-        Call  _post_data method
-        """
-        self.base.thaw_axes()
-        # create a 1D data plot
-        self._post_data()
-
-    def restore(self):
-        """
-        Restore the roughness for this layer.
-        """
-        self.outer_circle.restore()
-
-    def move(self, x, y, ev):
-        """
-        Process move to a new position, making sure that the move is allowed.
-        """
-        pass
-
-    def set_cursor(self, x, y):
-        pass
-
-    def getParams(self):
-        """
-        Store a copy of values of parameters of the slicer into a dictionary.
-
-        :return params: the dictionary created
-
-        """
-        params = {}
-        params["outer_radius"] = numpy.fabs(self.outer_circle._inner_mouse_x)
-        return params
-
-    def setParams(self, params):
-        """
-        Receive a dictionary and reset the slicer with values contained
-        in the values of the dictionary.
-
-        :param params: a dictionary containing name of slicer parameters and
-            values the user assigned to the slicer.
-        """
-        outer = numpy.fabs(params["outer_radius"])
-        # Update the picture
-        self.outer_circle.set_cursor(outer, self.outer_circle._inner_mouse_y)
-        # Post the data given the nbins entered by the user
-        self._post_data()
-
-    def draw(self):
-        self.base.update()
-
+
Index: src/sas/qtgui/Plotting/Slicers/Arc.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/Arc.py	(revision cee5c78929349ae10afc88cb8b95e0c907f1826a)
+++ src/sas/qtgui/Plotting/Slicers/Arc.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -2,7 +2,7 @@
     Arc slicer for 2D data
 """
-import math
+import numpy as np
 
-from .BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
 
 class ArcInteractor(BaseInteractor):
@@ -11,5 +11,5 @@
     """
     def __init__(self, base, axes, color='black', zorder=5, r=1.0,
-                 theta1=math.pi / 8, theta2=math.pi / 4):
+                 theta1=np.pi / 8, theta2=np.pi / 4):
         BaseInteractor.__init__(self, base, axes, color=color)
         self.markers = []
@@ -55,6 +55,6 @@
             Return arc radius
         """
-        radius = math.sqrt(math.pow(self._mouse_x, 2) + \
-                           math.pow(self._mouse_y, 2))
+        radius = np.sqrt(np.power(self._mouse_x, 2) + \
+                           np.power(self._mouse_y, 2))
         return radius
 
@@ -75,18 +75,18 @@
             self.theta2 = theta2
         while self.theta2 < self.theta1:
-            self.theta2 += (2 * math.pi)
-        while self.theta2 >= (self.theta1 + 2 * math.pi):
-            self.theta2 -= (2 * math.pi)
-        npts = int((self.theta2 - self.theta1) / (math.pi / 120))
+            self.theta2 += (2 * np.pi)
+        while self.theta2 >= (self.theta1 + 2 * np.pi):
+            self.theta2 -= (2 * np.pi)
+        npts = int((self.theta2 - self.theta1) / (np.pi / 120))
 
         if r is None:
-            self.radius = math.sqrt(math.pow(self._mouse_x, 2) + \
-                                     math.pow(self._mouse_y, 2))
+            self.radius = np.sqrt(np.power(self._mouse_x, 2) + \
+                                     np.power(self._mouse_y, 2))
         else:
             self.radius = r
         for i in range(self.npts):
             phi = (self.theta2 - self.theta1) / (self.npts - 1) * i + self.theta1
-            xval = 1.0 * self.radius * math.cos(phi)
-            yval = 1.0 * self.radius * math.sin(phi)
+            xval = 1.0 * self.radius * np.cos(phi)
+            yval = 1.0 * self.radius * np.sin(phi)
 
             x.append(xval)
Index: src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py	(revision b3e8629bf18b74f4214d6552e620fcbc4e73a28c)
+++ src/sas/qtgui/Plotting/Slicers/AzimutSlicer.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -4,6 +4,8 @@
 # TODO: NEED MAJOR REFACTOR
 #
-import math
-from .BaseInteractor import BaseInteractor
+import numpy as np
+from sas.qtgui.Plotting.Slicers.Arc import ArcInteractor
+from sas.qtgui.Plotting.Slicers.RadiusInteractor import RadiusInteractor
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
 
 class SectorInteractor(BaseInteractor):
@@ -22,9 +24,8 @@
         # # Number of points on the plot
         self.nbins = 20
-        theta1 = 2 * math.pi / 3
-        theta2 = -2 * math.pi / 3
+        theta1 = 2 * np.pi / 3
+        theta2 = -2 * np.pi / 3
 
         # Inner circle
-        from .Arc import ArcInteractor
         self.inner_circle = ArcInteractor(self, self.base.subplot,
                                           zorder=zorder,
@@ -40,5 +41,4 @@
         self.outer_circle.qmax = self.qmax * 1.2
         # self.outer_circle.set_cursor(self.base.qmax/1.8, 0)
-        from Edge import RadiusInteractor
         self.right_edge = RadiusInteractor(self, self.base.subplot,
                                            zorder=zorder + 1,
@@ -132,7 +132,4 @@
             phimin = self.left_edge.get_angle()
             phimax = self.right_edge.get_angle()
-        # print "phimin, phimax, rmin ,rmax",math.degrees(phimin),
-        # math.degrees(phimax), rmin ,rmax
-        # from sas.sascalc.dataloader.manipulations import SectorQ
 
         sect = new_sector(r_min=rmin, r_max=rmax,
Index: src/sas/qtgui/Plotting/Slicers/BoxSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/BoxSlicer.py	(revision 4992ff2626be19df7de9e5dfc0078b96bf47a75e)
+++ src/sas/qtgui/Plotting/Slicers/BoxSlicer.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -1,5 +1,5 @@
 import numpy
 
-from .BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
 from sas.qtgui.Plotting.PlotterData import Data1D
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
Index: src/sas/qtgui/Plotting/Slicers/BoxSum.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/BoxSum.py	(revision fbfc488f82ca4192217ad32b69f00fc4a4e137ab)
+++ src/sas/qtgui/Plotting/Slicers/BoxSum.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -8,5 +8,5 @@
 from sas.qtgui.Utilities.GuiUtils import formatNumber, toDouble
 
-from .BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
 from sas.sascalc.dataloader.manipulations import Boxavg
 from sas.sascalc.dataloader.manipulations import Boxsum
Index: src/sas/qtgui/Plotting/Slicers/RadiusInteractor.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/RadiusInteractor.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
+++ src/sas/qtgui/Plotting/Slicers/RadiusInteractor.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -0,0 +1,129 @@
+import numpy as np
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
+
+
+class RadiusInteractor(BaseInteractor):
+    """
+    Select an annulus through a 2D plot
+    """
+    def __init__(self, base, axes, color='black', zorder=5, arc1=None,
+                 arc2=None, theta=np.pi / 8):
+        """
+        """
+        _BaseInteractor.__init__(self, base, axes, color=color)
+        self.markers = []
+        self.axes = axes
+        self.r1 = arc1.get_radius()
+        self.r2 = arc2.get_radius()
+        self.theta = theta
+        self.save_theta = theta
+        self.move_stop = False
+        self.theta_left = None
+        self.theta_right = None
+        self.arc1 = arc1
+        self.arc2 = arc2
+        x1 = self.r1 * np.cos(self.theta)
+        y1 = self.r1 * np.sin(self.theta)
+        x2 = self.r2 * np.cos(self.theta)
+        y2 = self.r2 * np.sin(self.theta)
+        self.line = self.axes.plot([x1, x2], [y1, y2],
+                                   linestyle='-', marker='',
+                                   color=self.color,
+                                   visible=True)[0]
+        self.phi = theta
+        self.npts = 20
+        self.has_move = False
+        self.connect_markers([self.line])
+        self.update()
+
+    def set_layer(self, n):
+        """
+        """
+        self.layernum = n
+        self.update()
+
+    def clear(self):
+        """
+        """
+        self.clear_markers()
+        try:
+            self.line.remove()
+        except:
+            # Old version of matplotlib
+            for item in range(len(self.axes.lines)):
+                del self.axes.lines[0]
+
+    def get_angle(self):
+        """
+        """
+        return self.theta
+
+    def update(self, r1=None, r2=None, theta=None):
+        """
+        Draw the new roughness on the graph.
+        """
+        if r1 is not None:
+            self.r1 = r1
+        if r2 is not None:
+            self.r2 = r2
+        if theta is not None:
+            self.theta = theta
+        x1 = self.r1 * np.cos(self.theta)
+        y1 = self.r1 * np.sin(self.theta)
+        x2 = self.r2 * np.cos(self.theta)
+        y2 = self.r2 * np.sin(self.theta)
+        self.line.set(xdata=[x1, x2], ydata=[y1, y2])
+
+    def save(self, ev):
+        """
+        Remember the roughness for this layer and the next so that we
+        can restore on Esc.
+        """
+        self.save_theta = np.arctan2(ev.y, ev.x)
+        self.base.freeze_axes()
+
+    def moveend(self, ev):
+        """
+        """
+        self.has_move = False
+        self.base.moveend(ev)
+
+    def restore(self, ev):
+        """
+        Restore the roughness for this layer.
+        """
+        self.theta = self.save_theta
+
+    def move(self, x, y, ev):
+        """
+        Process move to a new position, making sure that the move is allowed.
+        """
+        self.theta = np.arctan2(y, x)
+        self.has_move = True
+        self.base.base.update()
+
+    def set_cursor(self, r_min, r_max, theta):
+        """
+        """
+        self.theta = theta
+        self.r1 = r_min
+        self.r2 = r_max
+        self.update()
+
+    def get_params(self):
+        """
+        """
+        params = {}
+        params["radius1"] = self.r1
+        params["radius2"] = self.r2
+        params["theta"] = self.theta
+        return params
+
+    def set_params(self, params):
+        """
+        """
+        x1 = params["radius1"]
+        x2 = params["radius2"]
+        theta = params["theta"]
+        self.set_cursor(x1, x2, theta)
+
Index: src/sas/qtgui/Plotting/Slicers/SectorSlicer.py
===================================================================
--- src/sas/qtgui/Plotting/Slicers/SectorSlicer.py	(revision d6b8a1dfaf6521ae4a9054d5195def2810d6d8bc)
+++ src/sas/qtgui/Plotting/Slicers/SectorSlicer.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -5,5 +5,5 @@
 import logging
 
-from .BaseInteractor import BaseInteractor
+from sas.qtgui.Plotting.Slicers.BaseInteractor import BaseInteractor
 from sas.qtgui.Plotting.PlotterData import Data1D
 import sas.qtgui.Utilities.GuiUtils as GuiUtils
@@ -283,4 +283,5 @@
         self.markers = []
         self.axes = axes
+        self.color = color
         # compute the value of the angle between the current line and
         # the x-axis
@@ -438,5 +439,6 @@
         if self.phi > numpy.pi:
             self.phi = 2 * numpy.pi - numpy.fabs(self.theta2 - self.theta)
-        self.base.base.update()
+        #self.base.base.update()
+        self.base.update()
 
     def set_cursor(self, x, y):
@@ -464,4 +466,5 @@
 
         self.markers = []
+        self.color = color
         self.axes = axes
         self.save_theta = theta
@@ -541,5 +544,6 @@
         self.theta = numpy.arctan2(y, x)
         self.has_move = True
-        self.base.base.update()
+        #self.base.base.update()
+        self.base.update()
 
     def set_cursor(self, x, y):
Index: src/sas/qtgui/Plotting/UI/MaskEditorUI.ui
===================================================================
--- src/sas/qtgui/Plotting/UI/MaskEditorUI.ui	(revision 3010f6810ba153e9cdad01da8b9b794f692d60b4)
+++ src/sas/qtgui/Plotting/UI/MaskEditorUI.ui	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -7,6 +7,6 @@
     <x>0</x>
     <y>0</y>
-    <width>642</width>
-    <height>431</height>
+    <width>687</width>
+    <height>507</height>
    </rect>
   </property>
@@ -104,4 +104,7 @@
       </sizepolicy>
      </property>
+     <property name="toolTip">
+      <string>Clear all the masks</string>
+     </property>
      <property name="text">
       <string>Reset</string>
@@ -116,4 +119,7 @@
        <verstretch>0</verstretch>
       </sizepolicy>
+     </property>
+     <property name="toolTip">
+      <string>Clear recent masks</string>
      </property>
      <property name="text">
Index: src/sas/qtgui/Utilities/GuiUtils.py
===================================================================
--- src/sas/qtgui/Utilities/GuiUtils.py	(revision c5e0d844708c4a7f2071bbba6132d4b2a67ce73a)
+++ src/sas/qtgui/Utilities/GuiUtils.py	(revision e20870bce5dcfe5fc479f9b0858c50abf55ae0d0)
@@ -251,4 +251,7 @@
     # Action Save Analysis triggered
     saveAnalysisSignal = QtCore.pyqtSignal()
+
+    # Mask Editor requested
+    maskEditorSignal = QtCore.pyqtSignal(Data2D)
 
 def updateModelItemWithPlot(item, update_data, name=""):
