class PlotWidget(QWidget):
    def __init__(self, parent=None):
        super(PlotWidget, self).__init__(parent)
        # create widgets
        self.canvas = PlotCanvas()
        self.toolbar = NavigationToolbar(self.canvas, self.canvas)
        self.toolbar.setSizePolicy(QSizePolicy.Preferred,
                                   QSizePolicy.Preferred)
        vbox = QVBoxLayout()
        vbox.addWidget(self.toolbar)
        vbox.addWidget(self.canvas)
        self.setLayout(vbox)

    def draw_curves(self, curve_names, data):
        self.canvas.axes.clear()
        self.canvas.axes.grid(True, color='gray')
        for name in curve_names:
            xdata, ydata = data[name]
            self.canvas.axes.plot(xdata, ydata, 'o-', label=name)[0]
        self.update_legend()
        self.canvas.draw()

    def update_legend(self):
        handles, labels = self.canvas.axes.get_legend_handles_labels()
        self.canvas.axes.legend(handles, labels, loc='upper left')
class PlotWidget(QWidget):
    def __init__(self, parent=None):
        super(PlotWidget, self).__init__(parent)
        # create widgets
        self.canvas = PlotCanvas()
        self.toolbar = NavigationToolbar(self.canvas, self.canvas)
        self.toolbar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        vbox = QVBoxLayout()
        vbox.addWidget(self.toolbar)
        vbox.addWidget(self.canvas)
        self.setLayout(vbox)

    def draw_curves (self, curve_names, data):
        self.canvas.axes.clear()
        self.canvas.axes.grid(True, color='gray')
        for name in curve_names:
            xdata, ydata = data[name]
            self.canvas.axes.plot(xdata, ydata, 'o-', label=name)[0]
        self.update_legend()
        self.canvas.draw()

    def update_legend(self):
        handles, labels = self.canvas.axes.get_legend_handles_labels()
        self.canvas.axes.legend(handles, labels, loc='upper left')
Ejemplo n.º 3
0
class CalibrationWindow(QtGui.QMainWindow):
    """
    Order on the layers in the right tab

    mask > data > massif > solid_angle
    """
    ZORDER = {"contour":5,
              "point": 4,
              "mask": 3,
              "data": 2,
              "massif": 1,
              "solidangle": 0,
              }
    INTERPOLATION = "nearest"
    ORIGIN = "lower"

    def __init__(self,):
        QtGui.QWidget.__init__(self)
        uic.loadUi("calibration_main.ui", self)
        self.connect(self.actionAbout_calibrate, SIGNAL("triggered()"), self.on_about)
        self.dpi = 100
        self.fig = self.canvas = self.mpl_toolbar = self.pix_coords_label = None
        self.axes = None
        # ar is for artists: plot, images or labels...
        self.ar_data = self.ar_mask = self.ar_massif = self.ar_contour = self.ar_solidangle = self.ar_points = None
        self.data = self.massif = self.solid_angle = self.mask = None
        self.display_checks = {}
        self.display_widget = None
        self.input_widget = None
        self.build_right_frame()
        self.build_input_tab()

    def on_about(self):
        msg = [__doc__,
               "",
               "Version date: \t%s" % __date__,
               "PyFAI version: \t%s" % pyFAI.version,
               "FabIO version: \t%s" % fabio.version,
               "Author: \t\t%s" % __author__,
               "Copyright: \t\t%s" % __copyright__,
               "License: \t\t%s" % __license__]
        QtGui.QMessageBox.about(self, "About calibrate", os.linesep.join(msg))

    def build_right_frame(self):
        "build the right frame that contains matplotlib widgets"

        self.fig = Figure(dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.image_frame)

        # Create the navigation toolbar, tied to the canvas
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.image_frame, coordinates=False)

        self.axes = self.fig.add_subplot(111)
        self.axes.set_visible(False)
        # Bind the 'pick' event for clicking on one of the bars
        self.canvas.mpl_connect('motion_notify_event', self.on_pick)

        self.pix_coords_label = QtGui.QLabel("x= None , y= None , i= None ", self)
        self.mpl_toolbar.addWidget(self.pix_coords_label)

        self.display_widget = uic.loadUi("display_widget.ui")

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(self.mpl_toolbar, alignment=QtCore.Qt.AlignTop)
        vbox.addWidget(self.canvas)
        vbox.addWidget(self.display_widget, alignment=QtCore.Qt.AlignBottom)
        self.image_frame.setLayout(vbox)

        # Enforce the size Policy of sub-widgets
        pol = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.mpl_toolbar.setSizePolicy(pol)
        self.display_widget.setSizePolicy(pol)
        self.canvas.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))

        # few signals about those new widgets:
        self.display_checks = {"data": self.display_widget.show_data,
                               "mask": self.display_widget.show_mask,
                               "massif": self.display_widget.show_massif,
                               "points": self.display_widget.show_points,
                               "contour": self.display_widget.show_contour,
                               "solidangle": self.display_widget.show_solidangle}
        for v in self.display_checks.itervalues():
            self.connect(v, SIGNAL("stateChanged(int)"), self.toggle_show)

    def build_input_tab(self):
        self.input_widget = InputWidget()
        self.scrollArea_input.setWidget(self.input_widget)

#        area->setWidget(widget);
#        box = QtGui.QHBoxLayout()
#        box.addWidget(self.input_widget)
#        self.input_frame.setLayout(box)
#        self.input_widget.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
#        self.input_frame.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))


    def on_pick(self, event):
        if event.inaxes and self.data is not None and self.data.any():
            if int(event.xdata) <= self.data.shape[1] and int(event.ydata) <= self.data.shape[0]:
                x = int(round(event.xdata))
                y = int(round(event.ydata))
                i = self.data[y, x]
                self.pix_coords_label.setText("x=%6d, y=%6d, I=%6g" % (x, y, i))
            else:
                self.pix_coords_label.setText("x= None , y= None , I= None ")
        else:
            self.pix_coords_label.setText("x= None , y= None , I= None ")

    def set_data(self, data, display=True, target="data"):
        """
        Display an array in the  data layer
        @param data: the numpy array with the data in it
        @param display: shall the data be displayed
        """
        self.__setattr__(target, data)
        artist = self.__getattribute__("ar_%s" % target)

        if self.axes is None:
            return
        show_data = self.calc_RGBA(data, target)

        if artist is None:
            artist = self.axes.imshow(show_data,
                                      zorder=self.ZORDER[target],
                                      interpolation=self.INTERPOLATION,
                                      origin=self.ORIGIN)
            self.__setattr__("ar_%s" % target, artist)
        else:
            artist.set_data(show_data)
        artist.set_visible(display)
        self.canvas.draw()
        if display:
            self.display_checks[target].setChecked(True)

    def calc_RGBA(self, data, target="data"):
        """
        Apply the colormap depending on the target

        @param data: array of floats
        @return: y,x,4 array of uint8

        TODO: one day, replace with cython implementation
        """
        if target == "mask":
            shape = data.shape
            mask = numpy.ascontiguousarray(data, dtype=bool)
            self.mask = mask
            res = numpy.zeros((shape[0], shape[1], 4), dtype=numpy.uint8)
            res[:, :, 0] = numpy.uint8(255) * mask
            res[:, :, 3] = numpy.uint8(255) * mask
            return res
        elif target == "data":
            npt_hist = 1000      # Number of data point in histogramming
            eps = 1e-3  # fraction to keep out

            if self.mask is not None:
                mask = numpy.ascontiguousarray(self.mask, dtype=bool)
                valid = data[numpy.logical_not(mask)]
                valid_min = valid.min()
                log_data = numpy.log1p(data - valid_min)
                valid = numpy.log1p(valid - valid_min)
            else:
                log_data = numpy.log1p(data - data.min())
                valid = log_data.ravel()

            size = valid.size
            sorted_v = numpy.sort(valid)
            start_idx = int(size * eps)
            end_idx = int(ceil(size * (1.0 - eps)))
            # remove first and last per thousand
            sorted_v = sorted_v[start_idx:end_idx]
            hist = numpy.histogram(sorted_v, npt_hist)[0].cumsum(dtype="float")
            x_range = numpy.linspace(sorted_v[0], sorted_v[-1], npt_hist, endpoint=False)
            eq_data = numpy.interp(log_data, x_range , hist / hist[-1], left=0, right=1)
            return matplotlib.cm.jet(eq_data, bytes=True)
        elif target == "solidangle":
            # should always be between 0 and 1 ...
            dmin = data.min()
            dmax = data.max()
            return matplotlib.cm.jet((data * 1.0 - dmin) / (dmax - dmin), bytes=True)
        elif target == "massif":
            mask = (data != 0)
            show_data = matplotlib.cm.jet(data * 1.0 / data.max(), bytes=True)
            show_data[:, :, 3] = mask * numpy.uint8(255)
            return show_data

    def any_display(self):
        if self.axes is not None:
            display = False
            for v in self.display_checks.values():
                display = display or v.isChecked()
            self.axes.set_visible(display)
            self.canvas.draw()

    def toggle_show(self):
        if self.axes is not None:
            display = False
            for k, v in self.display_checks.iteritems():
                artist = self.__getattribute__("ar_" + k)
                if artist is not None:
                    display_artsist = v.isChecked()
                    artist.set_visible(display_artsist)
                    display = display or display_artsist
            self.axes.set_visible(display)
            self.canvas.draw()