示例#1
0
 def create_layout_stuff(self):
   """ create grid layouts into which plotter widgets are inserted """
   if self.layout_parent is None or not self.layout_created:
     self.layout_parent = QWidget(self.wparent())
     self.layout = QGridLayout(self.layout_parent)
     self.QTextEdit = QTextEdit(self.layout_parent)
     self.layout.addWidget(self.QTextEdit, 0, 1)
     self.QTextEdit.hide()
     self.QTextEdit.setReadOnly(True)
     self.set_widgets(self.layout_parent,self.dataitem.caption,icon=self.icon())
     self.layout_created = True
   self._wtop = self.layout_parent;       
示例#2
0
    def createDataSelectorWidgets(self, parent, parent_layout):
        """Creates toolbuttons for complex values and Vells selection"""

        #print('in createDataSelectionWidgets')
        self._ds_top = top = QWidget(parent)
        parent_layout.addWidget(top)
        self._ds_lo = lotop = QVBoxLayout(top)
        lotop.setContentsMargins(0, 0, 0, 0)
        self._ds_complex = QWidget(top)
        self._ds_complex.setVisible(False)
        lotop.addWidget(self._ds_complex)
        lo = QVBoxLayout(self._ds_complex)
        lo.setContentsMargins(0, 0, 0, 0)
        lab = QLabel("complex:")
        lab.setAlignment(Qt.AlignHCenter)
        lo.addWidget(lab)
        # add complex selector
        lo0 = QHBoxLayout()
        lo0.setContentsMargins(0, 0, 0, 0)
        lo.addLayout(lo0)
        lo1 = QGridLayout()
        lo1.setContentsMargins(0, 0, 0, 0)
        lo1.setHorizontalSpacing(0)
        lo1.setVerticalSpacing(0)
        #   lo0.addStretch(1);
        lo0.addLayout(lo1)
        #   lo0.addStretch(1);
        bgrp = QButtonGroup(self._ds_complex)
        #   tbdesc = { self.AMP:(u"\u007Ca\u007C",0,0),self.PHASE:(u"\u03D5",0,1),self.REAL:("Re",1,0),self.IMAG:("Im",1,1) };
        #   tbdesc = { self.AMP:("\\u007Ca\\u007C",0,0),self.PHASE:("\\u0278",0,1),self.REAL:("Re",1,0),self.IMAG:("Im",1,1) };
        tbdesc = {
            self.AMP: ("Amp", 0, 0),
            self.PHASE: ("Pha", 0, 1),
            self.REAL: ("Re", 1, 0),
            self.IMAG: ("Im", 1, 1)
        }
        for label, qa in list(self._qas_complex.items()):
            tbtext, row, col = tbdesc[label]
            tb = QToolButton(self._ds_complex)
            lo1.addWidget(tb, row, col)
            bgrp.addButton(tb)
            tb.setText(tbtext)
            tb.setToolButtonStyle(Qt.ToolButtonTextOnly)
            tb.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum)
            tb.setCheckable(True)
            tb.setChecked(label is self.complex_component)
            tb.setMinimumWidth(32)
            tb.clicked[bool].connect(qa.setChecked)
            tb.clicked[bool].connect(self._change_complex)
            qa.triggered[bool].connect(tb.setChecked)
            self._tbs_complex[label] = tb
示例#3
0
 def __init__(self,
              array_shape=None,
              axis_label=None,
              axis_parms=None,
              num_axes=2,
              parent=None,
              name=""):
     QWidget.__init__(self, parent)
     # set default number of selectable axes to use 2-D QWT-based display
     self.selectable_axes = num_axes
     # create grid layout
     self.layout = QGridLayout(self)
     self.setWhatsThis(controller_instructions)
     self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
     self.construct_selectors(array_shape, axis_label, axis_parms)
示例#4
0
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        layout = QGridLayout(self)        
        # try to create a plot for SciPy arrays

        # make a curve and copy the data
        numpy_curve = QwtPlotCurve('y = lorentzian(x)')
        x = np.arange(0.0, 10.0, 0.01)
        y = lorentzian(x)
        numpy_curve.setData(x, y)
        # here, we know we can plot NumPy arrays
        numpy_plot = QwtPlot(self)
        numpy_plot.setTitle('numpy array')
        numpy_plot.setCanvasBackground(Qt.white)
        numpy_plot.plotLayout().setCanvasMargin(0)
        numpy_plot.plotLayout().setAlignCanvasToScales(True)
        # insert a curve and make it red
        numpy_curve.attach(numpy_plot)
        numpy_curve.setPen(QPen(Qt.red))
        layout.addWidget(numpy_plot, 0, 0)
        numpy_plot.replot()

        # create a plot widget for lists of Python floats
        list_plot = QwtPlot(self)
        list_plot.setTitle('Python list')
        list_plot.setCanvasBackground(Qt.white)
        list_plot.plotLayout().setCanvasMargin(0)
        list_plot.plotLayout().setAlignCanvasToScales(True)
        x = drange(0.0, 10.0, 0.01)
        y = [lorentzian(item) for item in x]
        # insert a curve, make it red and copy the lists
        list_curve = QwtPlotCurve('y = lorentzian(x)')
        list_curve.attach(list_plot)
        list_curve.setPen(QPen(Qt.red))
        list_curve.setData(x, y)
        layout.addWidget(list_plot, 0, 1)
        list_plot.replot()
示例#5
0
    def __init__(self, ax_number=1, axis_parms=None, parent=None, name=""):
        """ specify the layout of the spinbox and the slider """
        QWidget.__init__(self, parent)

        self.button = QPushButton(' ', self)
        self.ax_number = ax_number
        self.is_on = False
        self.axis_parms = axis_parms
        self.button_label = None

        self.spinbox = QSpinBox(self)
        self.spinbox.setMinimum(0)
        self.spinbox.setMaximum(99)
        self.spinbox.setWrapping(True)
        self.maxVal = 99

        self.slider = QSlider(Qt.Horizontal, self)
        self.slider.setTickPosition(QSlider.TicksBelow)
        self.slider.setTickInterval(10)
        self.slider.setRange(0, 99)
        self.maxVal = 99
        self.active = False

        self.label_info = QLabel(' ', self)

        self.resetValue()

        self.button.clicked.connect(self.emit_axis_number)
        self.slider.valueChanged.connect(self.update_slider)
        self.spinbox.valueChanged.connect(self.update_spinbox)

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.label_info, 0, 0)
        self.layout.addWidget(self.button, 1, 0)
        self.layout.addWidget(self.spinbox, 0, 2)
        self.layout.addWidget(self.slider, 1, 2)
示例#6
0
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        layout = QGridLayout(self)        
        # try to create a plot for SciPy arrays

        # make a curve and copy the data
        numpy_curve = QwtPlotCurve('y = lorentzian(x)')
        x = np.arange(0.0, 10.0, 0.01)
        y = lorentzian(x)
        numpy_curve.setData(x, y)
        # here, we know we can plot NumPy arrays
        numpy_plot = QwtPlot(self)
        numpy_plot.setTitle('numpy array')
        numpy_plot.setCanvasBackground(Qt.white)
        numpy_plot.plotLayout().setCanvasMargin(0)
        numpy_plot.plotLayout().setAlignCanvasToScales(True)
        # insert a curve and make it red
        numpy_curve.attach(numpy_plot)
        numpy_curve.setPen(QPen(Qt.red))
        layout.addWidget(numpy_plot, 0, 0)
        numpy_plot.replot()

        # create a plot widget for lists of Python floats
        list_plot = QwtPlot(self)
        list_plot.setTitle('Python list')
        list_plot.setCanvasBackground(Qt.white)
        list_plot.plotLayout().setCanvasMargin(0)
        list_plot.plotLayout().setAlignCanvasToScales(True)
        x = drange(0.0, 10.0, 0.01)
        y = [lorentzian(item) for item in x]
        # insert a curve, make it red and copy the lists
        list_curve = QwtPlotCurve('y = lorentzian(x)')
        list_curve.attach(list_plot)
        list_curve.setPen(QPen(Qt.red))
        list_curve.setData(x, y)
        layout.addWidget(list_plot, 0, 1)
        layout.addWidget(DataPlot(self),1,1)
        layout.addWidget(3dstl(self), 1, 0)
        list_plot.replot()
示例#7
0
 def setup(self, points, *args):
     x = np.linspace(.001, 20., points)
     y = (np.sin(x)/x)*np.cos(20*x)
     layout = QGridLayout()
     nbcol, col, row = 2, 0, 0
     for style, symbol in self.params(*args):
        layout.addWidget(BMPlot(style, x, y, getattr(QwtPlotCurve, style),
                                symbol=symbol), row, col)
        col += 1
        if col >= nbcol:
            row +=1
            col = 0
     self.text = QLineEdit()
     self.text.setReadOnly(True)
     self.text.setAlignment(Qt.AlignCenter)
     self.text.setText("Rendering plot...")
     layout.addWidget(self.text, row+1, 0, 1, 2)
     self.setLayout(layout)           
示例#8
0
class QuickRefPlotter(GriddedPlugin):
  """ a class to display quickref_help contents of a node in the browser """ 

  _icon = pixmaps.bars3d
  viewer_name = "QuickRef Display";
  def is_viewable (data):
    return len(data) > 0;
  is_viewable = staticmethod(is_viewable);

  def __init__(self,gw,dataitem,cellspec={},**opts):
    GriddedPlugin.__init__(self,gw,dataitem,cellspec=cellspec);
    """ Instantiate HippoDraw objects that are used to control
        various aspects of plotting, if the hippo plotter
        is instantiated.
    """
    self._rec = None;
    self._wtop = None;
    self.dataitem = dataitem
    self.layout_created = False
    self.reset_plot_stuff()

# back to 'real' work
    if dataitem and dataitem.data is not None:
      self.set_data(dataitem);

  def reset_plot_stuff(self):
    """ resets widgets to None. Needed if we have been putting
        out a message about Cache not containing results, etc
    """
    self.QTextEdit = None
    self.layout_parent = None
    self.layout = None


  def __del__(self):
    if self._window_controller:
      self._window_controller.closeAllWindows()
                                                                                           
  def wtop (self):
    """ function needed by Oleg for reasons known only to him! """
    return self._wtop;

  def create_layout_stuff(self):
    """ create grid layouts into which plotter widgets are inserted """
    if self.layout_parent is None or not self.layout_created:
      self.layout_parent = QWidget(self.wparent())
      self.layout = QGridLayout(self.layout_parent)
      self.QTextEdit = QTextEdit(self.layout_parent)
      self.layout.addWidget(self.QTextEdit, 0, 1)
      self.QTextEdit.hide()
      self.QTextEdit.setReadOnly(True)
      self.set_widgets(self.layout_parent,self.dataitem.caption,icon=self.icon())
      self.layout_created = True
    self._wtop = self.layout_parent;       

  def update_status(self, status):
     if not status is None:
       self.status_label.setText(status)

  def set_data (self,dataitem,default_open=None,**opts):
    """ This callback receives data from the meqbrowser, when the
    user has requested a QuickRef display . If there is a 
    'quickref_help' field (string) it will be shown via a
    QTextEdit widget in the browser.
    """

    if HAS_TIMBA: _dprint(3, '** in quickref_plotter:set_data callback')
    self._rec = dataitem.data;
    if HAS_TIMBA: _dprint(3, 'set_data: initial self._rec ', self._rec)
    if not isinstance(self._rec,record):
      # print '\n** self.rec not a record, but:',type(self._rec)
      pass
    elif "quickref_help" not in self._rec:
      # print '\n** self.rec does not have quickref_help field'
      pass
    else:
      qh = self._rec.quickref_help
      # print '\n** self.rec.quickref_help:',type(qh)
      if isinstance(qh,str):
        self.create_layout_stuff()
        self.QTextEdit.setText(qh)
        self.QTextEdit.show()
    return
示例#9
0
    def setVellsElementLabels(self, labels, dims):
        # do nothing when only one label, or when already set
        if len(labels) < 2 or self._qas_vells:
            return
        # make menu items
#   print 'in setVellsElementLabels, labels = ', labels
        for label in labels:
            # make menu action
            self._qas_vells[label] = va = self._qag_vells.addAction(str(label))
            va.setCheckable(True)
            # if first QAction, then check it
            if len(self._qas_vells) == 1:
                va.setChecked(True)
                self.vells_component = label
            self.vells_menu.addAction(va)
        self.vells_menu.menuAction().setVisible(True)

        # following does nothing at the moment
        for label in self.StokesComponents:
            self._qas_stokes[label] = vs = self._qag_stokes.addAction(label)
            vs.setCheckable(True)
            self.stokes_menu.addAction(vs)
        self.stokes_menu.menuAction().setVisible(True)
        # make grid of selector buttons, if dims are not too big

        if len(dims) == 1:
            dims = (1, dims[0])
        if len(dims) == 2 and min(*dims) >= 2 and max(*dims) <= 6:
            # for dims=1, make it 1xN
            # add vells selector
            self._ds_lo.addSpacing(16)
            self._ds_vells = QWidget(self._ds_top)
            self._ds_lo.addWidget(self._ds_vells)
            self._ds_stokes = QWidget(self._ds_top)
            self._ds_lo.addWidget(self._ds_stokes)
            self._ds_stokes.setVisible(False)
            lo = QVBoxLayout(self._ds_vells)
            lo.setContentsMargins(0, 0, 0, 0)
            lab = QLabel("element:")
            lab.setAlignment(Qt.AlignHCenter)
            lo.addWidget(lab)
            # add data selectors for correlations and Stokes
            lo0 = QVBoxLayout()
            lo0.setContentsMargins(0, 0, 0, 0)
            lo.addLayout(lo0)
            lo1 = QGridLayout()
            lo1.setContentsMargins(0, 0, 0, 0)
            lo1.setHorizontalSpacing(0)
            lo1.setVerticalSpacing(0)
            lo0.addLayout(lo1)
            bgrp = QButtonGroup(self._ds_vells)
            # make the labels
            for ilabel, label in enumerate(labels):
                # make toolbutton
                tb = QToolButton(self._ds_vells)
                bgrp.addButton(tb)
                self._tbs_vells[label] = tb
                tb.setText(str(label))
                tb.setToolButtonStyle(Qt.ToolButtonTextOnly)
                tb.setCheckable(True)
                tb.setChecked(label is self.vells_component)
                tb.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.Minimum)
                #      tb.setMinimumWidth(32);
                qa = self._qas_vells[label]
                tb.clicked[bool].connect(qa.setChecked)
                tb.clicked[bool].connect(self._change_vells)
                qa.triggered[bool].connect(tb.setChecked)
                # add to layout in correct place
                row, col = divmod(ilabel, dims[1])
                if dims[1] > 3:
                    col, row = row, col
                lo1.addWidget(tb, row, col)
            # show/hide controls
            self._ds_vells.setVisible(len(labels) > 1)

            lab = QLabel("stokes:")
            lab.setAlignment(Qt.AlignHCenter)
            lo0.addWidget(lab)

            lo2 = QGridLayout()
            lo2.setContentsMargins(0, 0, 0, 0)
            lo2.setHorizontalSpacing(0)
            lo2.setVerticalSpacing(0)
            lo0.addLayout(lo2)
            bgrp = QButtonGroup(self._ds_stokes)
            stdesc = {
                self.STOKES_I: ("I", 0, 0),
                self.STOKES_Q: ("Q", 0, 1),
                self.STOKES_U: ("U", 1, 0),
                self.STOKES_V: ("V", 1, 1)
            }
            for label, qa in list(self._qas_stokes.items()):
                tbtext, row, col = stdesc[label]
                tb = QToolButton(self._ds_stokes)
                lo2.addWidget(tb, row, col)
                bgrp.addButton(tb)
                tb.setText(tbtext)
                tb.setToolButtonStyle(Qt.ToolButtonTextOnly)
                tb.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.Minimum)
                tb.setCheckable(True)
                tb.setChecked(label is self.stokes_component)
                qa = self._qas_stokes[label]
                tb.clicked[bool].connect(qa.setChecked)
                tb.clicked[bool].connect(self._change_stokes)
                qa.triggered[bool].connect(tb.setChecked)
                self._tbs_complex[label] = tb
            # show/hide controls
            self._ds_stokes.setVisible(len(labels) > 1)
示例#10
0
class AxisRange(QWidget):
    """ a spinbox and a slider, either of which can be used to specify
        a value from within an allowed range
    """
    axis_number = pyqtSignal('int')
    Value_Changed = pyqtSignal(int, int, str)

    def __init__(self, ax_number=1, axis_parms=None, parent=None, name=""):
        """ specify the layout of the spinbox and the slider """
        QWidget.__init__(self, parent)

        self.button = QPushButton(' ', self)
        self.ax_number = ax_number
        self.is_on = False
        self.axis_parms = axis_parms
        self.button_label = None

        self.spinbox = QSpinBox(self)
        self.spinbox.setMinimum(0)
        self.spinbox.setMaximum(99)
        self.spinbox.setWrapping(True)
        self.maxVal = 99

        self.slider = QSlider(Qt.Horizontal, self)
        self.slider.setTickPosition(QSlider.TicksBelow)
        self.slider.setTickInterval(10)
        self.slider.setRange(0, 99)
        self.maxVal = 99
        self.active = False

        self.label_info = QLabel(' ', self)

        self.resetValue()

        self.button.clicked.connect(self.emit_axis_number)
        self.slider.valueChanged.connect(self.update_slider)
        self.spinbox.valueChanged.connect(self.update_spinbox)

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.label_info, 0, 0)
        self.layout.addWidget(self.button, 1, 0)
        self.layout.addWidget(self.spinbox, 0, 2)
        self.layout.addWidget(self.slider, 1, 2)

    def emit_axis_number(self):
        #     print 'emitting signal ', self.ax_number
        self.axis_number.emit(self.ax_number)

    def isOn(self):
        return self.is_on

    def setOn(self, value):
        self.is_on = value

    def getButton(self):
        return self.button

    def setLabel(self, label):
        """ set label on a button """
        self.button_label = label
        self.button.setText(label)

    def value(self):
        """ return current value of the slider """
        return self.slider.value()

    def hide_display(self):
        self.spinbox.hide()
        self.slider.hide()
        self.label_info.hide()

    def show_display(self):
        self.spinbox.show()
        self.slider.show()
        self.label_info.show()

    def resetValue(self):
        """ resets displayed values to zero """
        display_str = None
        if self.axis_parms is None or not self.active:
            display_str = ''
        else:
            delta_vells = (self.axis_parms[1] -
                           self.axis_parms[0]) / self.maxVal
            index = self.axis_parms[0] + 0.5 * delta_vells
            if abs(index) < 0.0000001:
                index = 0.0
            display_str = "%-.4g" % index
        self.slider.setValue(0)
        self.spinbox.setValue(0)
        self.label_info.setText(' ' + display_str)

    def setDisplayString(self, value):
        """ define current display string from Vells parameters """
        display_str = ''
        if not self.axis_parms is None:
            delta_vells = (self.axis_parms[1] -
                           self.axis_parms[0]) / self.maxVal
            index = self.axis_parms[0] + (value + 0.5) * delta_vells
            if abs(index) < 0.0000001:
                index = 0.0
            display_str = "%-.4g" % index
            self.label_info.setText(' ' + display_str)
        if not self.button_label is None:
            display_str = self.button_label + ' ' + display_str

        print('parms', self.ax_number, value, display_str)
        self.Value_Changed.emit(self.ax_number, value, display_str)

    def setRange(self, array_shape):
        """ make sure slider and spinbox both have same allowable range """
        self.slider.setRange(0, array_shape - 1)
        self.spinbox.setMaximum(array_shape - 1)
        self.maxVal = array_shape

    def setSliderColor(self, color):
        """ set color of slider - red or green """
        self.slider.setStyleSheet("QWidget { background-color: %s }" %
                                  color.name())

    def setActive(self, active):
        self.active = active

    def text(self):
        return self.label.text()

    def setText(self, s):
        self.label.setText(s)

    def update_slider(self, slider_value):
        """ synchronize spinbox value to current slider value """
        if self.active:
            self.spinbox.setValue(slider_value)
            self.setDisplayString(slider_value)
        else:
            self.resetValue()

    def update_spinbox(self, spin_value):
        """ synchronize slider value to current spinbox value """
        if self.active:
            self.slider.setValue(spin_value)
            self.setDisplayString(spin_value)
        else:
            self.spinbox.setValue(0)
示例#11
0
class ND_Controller(QWidget):
    defineSelectedAxes = pyqtSignal(int, int, int)
    sliderValueChanged = pyqtSignal(int, int, str)

    def __init__(self,
                 array_shape=None,
                 axis_label=None,
                 axis_parms=None,
                 num_axes=2,
                 parent=None,
                 name=""):
        QWidget.__init__(self, parent)
        # set default number of selectable axes to use 2-D QWT-based display
        self.selectable_axes = num_axes
        # create grid layout
        self.layout = QGridLayout(self)
        self.setWhatsThis(controller_instructions)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.construct_selectors(array_shape, axis_label, axis_parms)

    # __init__()

    def construct_selectors(self,
                            array_shape=None,
                            axis_label=None,
                            axis_parms=None):
        """ construct a group of AxisRange objects. These objects allow
          the user to specify which dimensions of an N-dimensional
          array are viewable in a 2 or 3-D display
      """
        self.green = QColor(0, 0, 0)
        self.green.setGreen(255)
        self.red = QColor(0, 0, 0)
        self.red.setRed(255)

        self.axis_parms = axis_parms

        # add control buttons and AxisRange selectors
        self.buttons = []
        self.button_number = []
        self.axis_controllers = []

        if array_shape is None:
            array_shape = []
            for i in range(len(axis_label)):
                array_shape.append(axis_parms[axis_label[i]][3])
        self.rank = 0
        for i in range(len(array_shape)):
            if array_shape[i] > 1:
                self.rank = self.rank + 1
        self.active_axes = {}
        self.num_selectors = -1
        row = 0
        col = 0
        for i in range(len(array_shape)):
            if array_shape[i] > 1:
                self.num_selectors = self.num_selectors + 1
                # add buttons
                button_label = None
                if not axis_label == None:
                    button_label = axis_label[i]
                else:
                    button_label = 'axis ' + str(i)
                if self.axis_parms is None:
                    parms = None
                else:
                    if axis_label[i] in self.axis_parms:
                        parms = self.axis_parms[axis_label[i]]
                    else:
                        parms = None
                self.axis_controllers.append(
                    AxisRange(ax_number=self.num_selectors,
                              axis_parms=parms,
                              parent=self))
                self.axis_controllers[self.num_selectors].setLabel(
                    button_label)
                self.axis_controllers[self.num_selectors].setRange(
                    array_shape[i])
                if self.num_selectors <= self.rank - (self.selectable_axes +
                                                      1):
                    self.axis_controllers[self.num_selectors].setSliderColor(
                        self.green)
                    self.axis_controllers[self.num_selectors].setActive(True)
                    self.axis_controllers[self.num_selectors].resetValue()
                    self.axis_controllers[self.num_selectors].show_display()
                else:
                    self.axis_controllers[self.num_selectors].setSliderColor(
                        self.red)
                    self.axis_controllers[self.num_selectors].hide_display()

                self.axis_controllers[self.num_selectors].axis_number.connect(
                    self.defineAxes)
                self.axis_controllers[
                    self.num_selectors].Value_Changed.connect(self.update)
                if col == 0:
                    spacer = QSpacerItem(22, 9, QSizePolicy.Expanding,
                                         QSizePolicy.Minimum)
                    self.layout.addItem(spacer, row, col)
                    col = col + 1
                self.layout.addWidget(
                    self.axis_controllers[self.num_selectors], row, col)
                self.buttons.append(
                    self.axis_controllers[self.num_selectors].getButton())
                self.button_number.append(i)
                #         self.buttons[self.num_selectors].setToggleButton(True)
                if self.num_selectors <= self.rank - (self.selectable_axes +
                                                      1):
                    self.axis_controllers[self.num_selectors].setOn(False)
                else:
                    self.axis_controllers[self.num_selectors].setOn(True)
                    self.active_axes[self.num_selectors] = True
                if col >= 4:
                    col = 0
                    row = row + 1
                else:
                    col = col + 1

# add one to get number of active selector buttons
        self.num_selectors = self.num_selectors + 1

    def showDisplay(self, show_self):
        if show_self > 0:
            self.show()
        else:
            self.hide()

    # showDisplay

    def set_num_selectable_axes(self, num_axes=2):
        self.selectable_axes = num_axes
        self.redefineAxes()

    def get_num_selectors(self):
        """ gets number of AxisRange objects in the Controller """
        return self.num_selectors

    def defineAxes(self, button_id, do_on=False):
        """ When a button is pressed, this function figures out if
            the user has selected the required number of dimensions
            for extraction. The AxisRange objects for those
            dimensions are colored red.  All data for the selected
            dimensions will be displayed. The remaining AxisRange
            objects are colored green - they enable the user to
            select a single value from their associated dimension.
        """
        #       print 'defineAxes button id = ', button_id
        if not self.active_axes is None and len(
                self.active_axes) == self.selectable_axes:
            self.resetAxes()
        self.axis_controllers[button_id].setOn(True)
        #       if do_on:
        #         self.axis_controllers[button_id].setOn(True)
        if self.axis_controllers[button_id].isOn():
            self.axis_controllers[button_id].setSliderColor(self.red)
            #         self.axis_controllers[button_id].hide_display()
            self.active_axes[button_id] = True
            if len(self.active_axes) == self.selectable_axes:
                first_axis = None
                second_axis = None
                third_axis = None
                for i in range(self.num_selectors):
                    if i in self.active_axes:
                        if first_axis is None:
                            first_axis = self.button_number[i]
                        elif second_axis is None:
                            second_axis = self.button_number[i]
                        else:
                            if self.selectable_axes == 3:
                                if third_axis is None:
                                    third_axis = self.button_number[i]
                        self.axis_controllers[i].setSliderColor(self.red)
                        self.axis_controllers[i].setActive(False)
                        self.axis_controllers[i].hide_display()
                    else:
                        self.axis_controllers[i].setSliderColor(self.green)
                        self.axis_controllers[i].setActive(True)
                        self.axis_controllers[i].show_display()
                    self.axis_controllers[i].resetValue()
                self.defineSelectedAxes.emit(first_axis, second_axis,
                                             third_axis)
        else:
            if button_id in self.active_axes:
                del self.active_axes[button_id]
            self.axis_controllers[button_id].setSliderColor(self.red)
#         self.axis_controllers[button_id].hide_display()
# defineAxes

    def redefineAxes(self):
        self.defineAxes(self.num_selectors - 1, True)
        self.defineAxes(self.num_selectors - 2, True)

    # redefineAxes

    def resetAxes(self):
        """ resets all AxisRange objects to be inactive """
        for i in range(self.num_selectors):
            self.axis_controllers[i].setOn(False)
            self.axis_controllers[i].setSliderColor(self.red)
            self.axis_controllers[i].setActive(False)
            #         self.axis_controllers[i].hide_display()
            self.axis_controllers[i].resetValue()
        self.active_axes = {}

    # resetAxes

    def update(self, axis_number, slider_value, display_string):
        """ emits a signal to the data selection program giving
          the new value of an active dimension index 
      """
        print('Caught ', axis_number, slider_value, display_string)
        if not axis_number in self.active_axes:
            if not self.axis_controllers[axis_number].isOn():
                self.sliderValueChanged.emit(self.button_number[axis_number],
                                             slider_value, display_string)
            else:
                self.axis_controllers[axis_number].resetValue()
        else:
            self.axis_controllers[axis_number].resetValue()