Example #1
0
 def create_graphics(self):
     self.spectrum_plot = self.pg_layout.addPlot(labels={
         'left': 'Intensity',
         'bottom': '2 Theta'
     })
     self.spectrum_plot.setLabel('bottom', u'2θ', u'°')
     self.view_box = self.spectrum_plot.vb
     self.legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)
     self.phases_legend = LegendItem(horSpacing=20,
                                     box=False,
                                     verSpacing=-3)
Example #2
0
class SpectrumView(object):
    def __init__(self, pg_layout):
        self.pg_layout = pg_layout
        self.create_graphics()
        self.create_main_plot()
        self.create_pos_line()
        self.modify_mouse_behavior()
        self.phases = []
        self.overlays = []
        self.overlay_names = []
        self.overlay_show = []
        self.mouse_move_observer = []
        self.left_click_observer = []

    def add_left_click_observer(self, function):
        self.left_click_observer.append(function)

    def add_mouse_move_observer(self, function):
        self.mouse_move_observer.append(function)

    def create_graphics(self):
        self.spectrum_plot = self.pg_layout.addPlot(labels={'left': 'Intensity', 'bottom': '2 Theta'})
        self.spectrum_plot.setLabel('bottom', u'2θ', u'°')
        self.view_box = self.spectrum_plot.vb
        self.legend = LegendItem(horSpacing=20, box=False)
        self.phases_legend = LegendItem(horSpacing=20, box=False)


    def create_main_plot(self):
        self.plot_item = pg.PlotDataItem(np.linspace(0, 10), np.sin(np.linspace(10, 3)),
                                         pen=pg.mkPen(color=(255, 255, 255), width=2))
        self.spectrum_plot.addItem(self.plot_item)
        self.legend.addItem(self.plot_item, '')
        self.plot_name = ''
        self.legend.setParentItem(self.spectrum_plot.vb)
        self.legend.anchor(itemPos=(1, 0), parentPos=(1, 0), offset=(-10, -10))
        self.phases_legend.setParentItem(self.spectrum_plot.vb)
        self.phases_legend.anchor(itemPos=(0, 0), parentPos=(0, 0), offset=(0, -10))


    def create_pos_line(self):
        self.pos_line = pg.InfiniteLine(pen=pg.mkPen(color=(0, 255, 0), width=2))
        self.spectrum_plot.addItem(self.pos_line)

    def set_pos_line(self, x):
        self.pos_line.setPos(x)

    def plot_data(self, x, y, name=None):
        self.plot_item.setData(x, y)
        if name is not None:
            self.legend.legendItems[0][1].setText(name)
            self.plot_name = name

    def add_overlay(self, spectrum, show=True):
        x, y = spectrum.data
        color = calculate_color(len(self.overlays) + 1)
        self.overlays.append(pg.PlotDataItem(x, y, pen=pg.mkPen(color=color, width=1.5)))
        self.overlay_names.append(spectrum.name)
        self.overlay_show.append(True)
        if show:
            self.spectrum_plot.addItem(self.overlays[-1])
            self.legend.addItem(self.overlays[-1], spectrum.name)

    def del_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlays.remove(self.overlays[ind])
        self.overlay_names.remove(self.overlay_names[ind])
        self.overlay_show.remove(self.overlay_show[ind])

    def hide_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlay_show[ind] = False

    def show_overlay(self, ind):
        self.spectrum_plot.addItem(self.overlays[ind])
        self.legend.addItem(self.overlays[ind], self.overlay_names[ind])
        self.overlay_show[ind] = True

    def update_overlay(self, spectrum, ind):
        x, y = spectrum.data
        self.overlays[ind].setData(x, y)

    def add_phase(self, name, positions, intensities, baseline):
        self.phases.append(PhasePlot(self.spectrum_plot, self.phases_legend, positions, intensities, name, baseline))

    def update_phase(self, ind, positions, intensities, name=None, baseline=0):
        self.phases[ind].create_items(positions, intensities, name, baseline)

    def update_phase_intensities(self, ind, positions, intensities, baseline=0):
        if len(self.phases):
            self.phases[ind].update_intensities(positions, intensities, baseline)

    def del_phase(self, ind):
        self.phases[ind].remove()
        self.phases.remove(self.phases[ind])

    def plot_vertical_lines(self, positions, phase_index=0, name=None):
        if len(self.phases) <= phase_index:
            self.phases.append(PhaseLinesPlot(self.spectrum_plot, positions))
        else:
            self.phases[phase_index].set_data(positions, name)

    def mouseMoved(self, pos):
        pos = self.plot_item.mapFromScene(pos)
        for function in self.mouse_move_observer:
            function(pos.x(), pos.y())


    def modify_mouse_behavior(self):
        #different mouse handlers
        self.view_box.setMouseMode(self.view_box.RectMode)

        self.pg_layout.scene().sigMouseMoved.connect(self.mouseMoved)
        self.view_box.mouseClickEvent = self.myMouseClickEvent
        self.view_box.mouseDragEvent = self.myMouseDragEvent
        self.view_box.mouseDoubleClickEvent = self.myMouseDoubleClickEvent
        self.view_box.wheelEvent = self.myWheelEvent


    def myMouseClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton:
            view_range = np.array(self.view_box.viewRange()) * 2
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and \
                            (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
            else:
                self.view_box.scaleBy(2)
        if ev.button() == QtCore.Qt.LeftButton:
            pos = self.view_box.mapFromScene(ev.pos())
            pos = self.plot_item.mapFromScene(2 * ev.pos() - pos)
            x = pos.x()
            y = pos.y()
            for function in self.left_click_observer:
                function(x, y)


    def myMouseDoubleClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton:
            self.view_box.autoRange()
            self.view_box.enableAutoRange()


    def myMouseDragEvent(self, ev, axis=None):
        #most of this code is copied behavior of left click mouse drag from the original code
        ev.accept()
        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif *= -1
        ## Ignore axes if mouse is disabled
        mouseEnabled = np.array(self.view_box.state['mouseEnabled'], dtype=np.float)
        mask = mouseEnabled.copy()
        if axis is not None:
            mask[1 - axis] = 0.0

        if ev.button() == QtCore.Qt.RightButton:
            #determine the amount of translation
            tr = dif * mask
            tr = self.view_box.mapToView(tr) - self.view_box.mapToView(pg.Point(0, 0))
            x = tr.x()
            y = tr.y()

            self.view_box.translateBy(x=x, y=y)
            self.view_box.sigRangeChangedManually.emit(self.view_box.state['mouseEnabled'])
        else:
            pg.ViewBox.mouseDragEvent(self.view_box, ev)


    def myWheelEvent(self, ev):
        if ev.delta() > 0:
            pg.ViewBox.wheelEvent(self.view_box, ev)
        else:
            view_range = np.array(self.view_box.viewRange())
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and \
                            (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
            else:
                pg.ViewBox.wheelEvent(self.view_box, ev)
Example #3
0
 def create_graphics(self):
     self.spectrum_plot = self.pg_layout.addPlot(labels={'left': 'Intensity', 'bottom': '2 Theta'})
     self.spectrum_plot.setLabel('bottom', u'2θ', u'°')
     self.view_box = self.spectrum_plot.vb
     self.legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)
     self.phases_legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)
Example #4
0
class SpectrumView(QtCore.QObject):
    mouse_moved = QtCore.pyqtSignal(float, float)
    mouse_left_clicked = QtCore.pyqtSignal(float, float)
    range_changed = QtCore.pyqtSignal(list)

    def __init__(self, pg_layout):
        super(SpectrumView, self).__init__()
        self.pg_layout = pg_layout
        self.create_graphics()
        self.create_main_plot()
        self.create_pos_line()
        self.modify_mouse_behavior()
        self._auto_range = True
        self.phases = []
        self.phases_vlines = []
        self.overlays = []
        self.overlay_names = []
        self.overlay_show = []

    def create_graphics(self):
        self.spectrum_plot = self.pg_layout.addPlot(labels={'left': 'Intensity', 'bottom': '2 Theta'})
        self.spectrum_plot.setLabel('bottom', u'2θ', u'°')
        self.view_box = self.spectrum_plot.vb
        self.legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)
        self.phases_legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)


    def create_main_plot(self):
        self.plot_item = pg.PlotDataItem(np.linspace(0, 10), np.sin(np.linspace(10, 3)),
                                         pen=pg.mkPen(color=(255, 255, 255), width=2))
        self.spectrum_plot.addItem(self.plot_item)
        self.legend.addItem(self.plot_item, '')
        self.plot_name = ''
        self.legend.setParentItem(self.spectrum_plot.vb)
        self.legend.anchor(itemPos=(1, 0), parentPos=(1, 0), offset=(-10, -10))
        self.phases_legend.setParentItem(self.spectrum_plot.vb)
        self.phases_legend.anchor(itemPos=(0, 0), parentPos=(0, 0), offset=(0, -10))

    def create_pos_line(self):
        self.pos_line = pg.InfiniteLine(pen=pg.mkPen(color=(0, 255, 0), width=1.5))
        self.spectrum_plot.addItem(self.pos_line)

    def set_pos_line(self, x):
        self.pos_line.setPos(x)

    def get_pos_line(self):
        return self.pos_line.value()

    def plot_data(self, x, y, name=None):
        self.plot_item.setData(x, y)
        if name is not None:
            self.legend.legendItems[0][1].setText(name)
            self.plot_name = name
        self.update_x_limits()
        self.legend.updateSize()

    def update_x_limits(self):
        x_range = list(self.plot_item.dataBounds(0))
        for ind, overlay in enumerate(self.overlays):
            if self.overlay_show[ind]:
                x_range_overlay = overlay.dataBounds(0)
                if x_range_overlay[0] < x_range[0]:
                    x_range[0] = x_range_overlay[0]
                if x_range_overlay[1] > x_range[1]:
                    x_range[1] = x_range_overlay[1]

        diff = x_range[1] - x_range[0]
        x_range = [x_range[0] - 0.02 * diff,
                   x_range[1] + 0.02 * diff]

        self.view_box.setLimits(xMin=x_range[0], xMax=x_range[1],
                                minXRange=x_range[0], maxXRange=x_range[1])

    def add_overlay(self, spectrum, show=True):
        x, y = spectrum.data
        color = calculate_color(len(self.overlays) + 1)
        self.overlays.append(pg.PlotDataItem(x, y, pen=pg.mkPen(color=color, width=1.5)))
        self.overlay_names.append(spectrum.name)
        self.overlay_show.append(True)
        if show:
            self.spectrum_plot.addItem(self.overlays[-1])
            self.legend.addItem(self.overlays[-1], spectrum.name)
            self.update_x_limits()
        return color

    def del_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlays.remove(self.overlays[ind])
        self.overlay_names.remove(self.overlay_names[ind])
        self.overlay_show.remove(self.overlay_show[ind])
        self.update_x_limits()

    def hide_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.hideItem(ind+1)
        self.overlay_show[ind] = False
        self.update_x_limits()

    def show_overlay(self, ind):
        self.spectrum_plot.addItem(self.overlays[ind])
        self.legend.showItem(ind+1)
        self.overlay_show[ind] = True
        self.update_x_limits()

    def update_overlay(self, spectrum, ind):
        x, y = spectrum.data
        self.overlays[ind].setData(x, y)
        if self._auto_range:
            self.view_box.autoRange()
            self.view_box.enableAutoRange()

    def get_overlay_color(self, ind):
        pass

    def set_overlay_color(self, ind, color):
        self.overlays[ind].setPen(pg.mkPen(color=color, width=1.5))
        self.legend.setItemColor(ind+1, color)

    def rename_overlay(self, ind, name):
        self.legend.renameItem(ind+1, name)

    def add_phase(self, name, positions, intensities, baseline):
        self.phases.append(PhasePlot(self.spectrum_plot, self.phases_legend, positions, intensities, name, baseline))
        return self.phases[-1].color

    # def update_phase(self, ind, positions, intensities, name=None, baseline=0):
    #     self.phases[ind].create_items(positions, intensities, name, baseline)

    def set_phase_color(self, ind, color):
        self.phases[ind].set_color(color)
        self.phases_legend.setItemColor(ind, color)

    def hide_phase(self, ind):
        self.phases[ind].hide()
        self.phases_legend.hideItem(ind)

    def show_phase(self, ind):
        self.phases[ind].show()
        self.phases_legend.showItem(ind)

    def rename_phase(self, ind, name):
        self.phases_legend.renameItem(ind, name)

    def update_phase_intensities(self, ind, positions, intensities, baseline=0):
        if len(self.phases):
            self.phases[ind].update_intensities(positions, intensities, baseline)

    def update_phase_line_visibilities(self):
        x_range = self.plot_item.dataBounds(0)
        for phase in self.phases:
            phase.update_visibilities(x_range)

    def del_phase(self, ind):
        self.phases[ind].remove()
        self.phases.remove(self.phases[ind])

    def plot_vertical_lines(self, positions, name=None):
        if len(self.phases_vlines) > 0:
            self.phases_vlines[0].set_data(positions, name)
        else:
            self.phases_vlines.append(PhaseLinesPlot(self.spectrum_plot, positions))


    def save_png(self, filename):
        exporter = ImageExporter(self.spectrum_plot)
        exporter.export(filename)

    def save_svg(self, filename):
        self.invert_color()
        exporter = SVGExporter(self.spectrum_plot)
        exporter.export(filename)
        self.norm_color()

    def _invert_color(self):
        self.spectrum_plot.getAxis('bottom').setPen('k')
        self.spectrum_plot.getAxis('left').setPen('k')
        self.plot_item.setPen('k')
        self.legend.legendItems[0][1].setAttr('color', '000')
        self.legend.legendItems[0][1].setText(self.legend.legendItems[0][1].text)

    def _norm_color(self):
        self.spectrum_plot.getAxis('bottom').setPen('w')
        self.spectrum_plot.getAxis('left').setPen('w')
        self.plot_item.setPen('w')
        self.legend.legendItems[0][1].setAttr('color', 'FFF')
        self.legend.legendItems[0][1].setText(self.legend.legendItems[0][1].text)

    def mouseMoved(self, pos):
        pos = self.plot_item.mapFromScene(pos)
        self.mouse_moved.emit(pos.x(), pos.y())


    def modify_mouse_behavior(self):
        #different mouse handlers
        self.view_box.setMouseMode(self.view_box.RectMode)

        self.pg_layout.scene().sigMouseMoved.connect(self.mouseMoved)
        self.view_box.mouseClickEvent = self.myMouseClickEvent
        self.view_box.mouseDragEvent = self.myMouseDragEvent
        self.view_box.mouseDoubleClickEvent = self.myMouseDoubleClickEvent
        self.view_box.wheelEvent = self.myWheelEvent


    def myMouseClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton or \
                (ev.button() == QtCore.Qt.LeftButton and \
                             ev.modifiers() & QtCore.Qt.ControlModifier):
            view_range = np.array(self.view_box.viewRange()) * 2
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            if (view_range[0][1] - view_range[0][0]) > x_range:
                self._auto_range = True
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
            else:
                self._auto_range = False
                self.view_box.scaleBy(2)
            self.view_box.sigRangeChangedManually.emit(self.view_box.state['mouseEnabled'])
        elif ev.button() == QtCore.Qt.LeftButton:
            pos = self.view_box.mapFromScene(ev.pos())
            pos = self.plot_item.mapFromScene(2 * ev.pos() - pos)
            x = pos.x()
            y = pos.y()
            self.mouse_left_clicked.emit(x, y)


    def myMouseDoubleClickEvent(self, ev):
        if (ev.button() == QtCore.Qt.RightButton) or (ev.button() == QtCore.Qt.LeftButton and \
                                                                  ev.modifiers() & QtCore.Qt.ControlModifier):
            self.view_box.autoRange()
            self.view_box.enableAutoRange()
            self._auto_range = True
            self.view_box.sigRangeChangedManually.emit(self.view_box.state['mouseEnabled'])


    def myMouseDragEvent(self, ev, axis=None):
        #most of this code is copied behavior of left click mouse drag from the original code
        ev.accept()
        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif *= -1

        if ev.button() == QtCore.Qt.RightButton or \
                (ev.button() == QtCore.Qt.LeftButton and \
                             ev.modifiers() & QtCore.Qt.ControlModifier):
            #determine the amount of translation
            tr = dif
            tr = self.view_box.mapToView(tr) - self.view_box.mapToView(pg.Point(0, 0))
            x = tr.x()
            y = tr.y()

            self.view_box.translateBy(x=x, y=y)
        else:
            self._auto_range = False
            pg.ViewBox.mouseDragEvent(self.view_box, ev)

        self.view_box.sigRangeChangedManually.emit(self.view_box.state['mouseEnabled'])


    def myWheelEvent(self, ev, axis=None, *args):
        if ev.delta() > 0:
            pg.ViewBox.wheelEvent(self.view_box, ev, axis)

            self._auto_range = False
            # axis_range = self.spectrum_plot.viewRange()
            # self.range_changed.emit(axis_range)
        else:
            view_range = np.array(self.view_box.viewRange())
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and \
                            (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
                self._auto_range = True
            else:
                self._auto_range = False
                pg.ViewBox.wheelEvent(self.view_box, ev)
        self.view_box.sigRangeChangedManually.emit(self.view_box.state['mouseEnabled'])
Example #5
0
class SpectrumView(QtCore.QObject):
    mouse_moved = QtCore.pyqtSignal(float, float)
    mouse_left_clicked = QtCore.pyqtSignal(float, float)
    range_changed = QtCore.pyqtSignal(list)

    def __init__(self, pg_layout):
        super(SpectrumView, self).__init__()
        self.pg_layout = pg_layout
        self.create_graphics()
        self.create_main_plot()
        self.create_pos_line()
        self.modify_mouse_behavior()
        self._auto_range = True
        self.phases = []
        self.phases_vlines = []
        self.overlays = []
        self.overlay_names = []
        self.overlay_show = []

    def create_graphics(self):
        self.spectrum_plot = self.pg_layout.addPlot(labels={
            'left': 'Intensity',
            'bottom': '2 Theta'
        })
        self.spectrum_plot.setLabel('bottom', u'2θ', u'°')
        self.view_box = self.spectrum_plot.vb
        self.legend = LegendItem(horSpacing=20, box=False, verSpacing=-3)
        self.phases_legend = LegendItem(horSpacing=20,
                                        box=False,
                                        verSpacing=-3)

    def create_main_plot(self):
        self.plot_item = pg.PlotDataItem(np.linspace(0, 10),
                                         np.sin(np.linspace(10, 3)),
                                         pen=pg.mkPen(color=(255, 255, 255),
                                                      width=2))
        self.spectrum_plot.addItem(self.plot_item)
        self.legend.addItem(self.plot_item, '')
        self.plot_name = ''
        self.legend.setParentItem(self.spectrum_plot.vb)
        self.legend.anchor(itemPos=(1, 0), parentPos=(1, 0), offset=(-10, -10))
        self.phases_legend.setParentItem(self.spectrum_plot.vb)
        self.phases_legend.anchor(itemPos=(0, 0),
                                  parentPos=(0, 0),
                                  offset=(0, -10))

    def create_pos_line(self):
        self.pos_line = pg.InfiniteLine(
            pen=pg.mkPen(color=(0, 255, 0), width=1.5))
        self.spectrum_plot.addItem(self.pos_line)

    def set_pos_line(self, x):
        self.pos_line.setPos(x)

    def get_pos_line(self):
        return self.pos_line.value()

    def plot_data(self, x, y, name=None):
        self.plot_item.setData(x, y)
        if name is not None:
            self.legend.legendItems[0][1].setText(name)
            self.plot_name = name
        self.update_x_limits()
        self.legend.updateSize()

    def update_x_limits(self):
        x_range = list(self.plot_item.dataBounds(0))
        for ind, overlay in enumerate(self.overlays):
            if self.overlay_show[ind]:
                x_range_overlay = overlay.dataBounds(0)
                if x_range_overlay[0] < x_range[0]:
                    x_range[0] = x_range_overlay[0]
                if x_range_overlay[1] > x_range[1]:
                    x_range[1] = x_range_overlay[1]

        diff = x_range[1] - x_range[0]
        x_range = [x_range[0] - 0.02 * diff, x_range[1] + 0.02 * diff]

        self.view_box.setLimits(xMin=x_range[0],
                                xMax=x_range[1],
                                minXRange=x_range[0],
                                maxXRange=x_range[1])

    def add_overlay(self, spectrum, show=True):
        x, y = spectrum.data
        color = calculate_color(len(self.overlays) + 1)
        self.overlays.append(
            pg.PlotDataItem(x, y, pen=pg.mkPen(color=color, width=1.5)))
        self.overlay_names.append(spectrum.name)
        self.overlay_show.append(True)
        if show:
            self.spectrum_plot.addItem(self.overlays[-1])
            self.legend.addItem(self.overlays[-1], spectrum.name)
            self.update_x_limits()
        return color

    def del_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlays.remove(self.overlays[ind])
        self.overlay_names.remove(self.overlay_names[ind])
        self.overlay_show.remove(self.overlay_show[ind])
        self.update_x_limits()

    def hide_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.hideItem(ind + 1)
        self.overlay_show[ind] = False
        self.update_x_limits()

    def show_overlay(self, ind):
        self.spectrum_plot.addItem(self.overlays[ind])
        self.legend.showItem(ind + 1)
        self.overlay_show[ind] = True
        self.update_x_limits()

    def update_overlay(self, spectrum, ind):
        x, y = spectrum.data
        self.overlays[ind].setData(x, y)
        if self._auto_range:
            self.view_box.autoRange()
            self.view_box.enableAutoRange()

    def get_overlay_color(self, ind):
        pass

    def set_overlay_color(self, ind, color):
        self.overlays[ind].setPen(pg.mkPen(color=color, width=1.5))
        self.legend.setItemColor(ind + 1, color)

    def rename_overlay(self, ind, name):
        self.legend.renameItem(ind + 1, name)

    def add_phase(self, name, positions, intensities, baseline):
        self.phases.append(
            PhasePlot(self.spectrum_plot, self.phases_legend, positions,
                      intensities, name, baseline))
        return self.phases[-1].color

    # def update_phase(self, ind, positions, intensities, name=None, baseline=0):
    #     self.phases[ind].create_items(positions, intensities, name, baseline)

    def set_phase_color(self, ind, color):
        self.phases[ind].set_color(color)
        self.phases_legend.setItemColor(ind, color)

    def hide_phase(self, ind):
        self.phases[ind].hide()
        self.phases_legend.hideItem(ind)

    def show_phase(self, ind):
        self.phases[ind].show()
        self.phases_legend.showItem(ind)

    def rename_phase(self, ind, name):
        self.phases_legend.renameItem(ind, name)

    def update_phase_intensities(self,
                                 ind,
                                 positions,
                                 intensities,
                                 baseline=0):
        if len(self.phases):
            self.phases[ind].update_intensities(positions, intensities,
                                                baseline)

    def update_phase_line_visibilities(self):
        x_range = self.plot_item.dataBounds(0)
        for phase in self.phases:
            phase.update_visibilities(x_range)

    def del_phase(self, ind):
        self.phases[ind].remove()
        self.phases.remove(self.phases[ind])

    def plot_vertical_lines(self, positions, name=None):
        if len(self.phases_vlines) > 0:
            self.phases_vlines[0].set_data(positions, name)
        else:
            self.phases_vlines.append(
                PhaseLinesPlot(self.spectrum_plot, positions))

    def save_png(self, filename):
        exporter = ImageExporter(self.spectrum_plot)
        exporter.export(filename)

    def save_svg(self, filename):
        self.invert_color()
        exporter = SVGExporter(self.spectrum_plot)
        exporter.export(filename)
        self.norm_color()

    def _invert_color(self):
        self.spectrum_plot.getAxis('bottom').setPen('k')
        self.spectrum_plot.getAxis('left').setPen('k')
        self.plot_item.setPen('k')
        self.legend.legendItems[0][1].setAttr('color', '000')
        self.legend.legendItems[0][1].setText(
            self.legend.legendItems[0][1].text)

    def _norm_color(self):
        self.spectrum_plot.getAxis('bottom').setPen('w')
        self.spectrum_plot.getAxis('left').setPen('w')
        self.plot_item.setPen('w')
        self.legend.legendItems[0][1].setAttr('color', 'FFF')
        self.legend.legendItems[0][1].setText(
            self.legend.legendItems[0][1].text)

    def mouseMoved(self, pos):
        pos = self.plot_item.mapFromScene(pos)
        self.mouse_moved.emit(pos.x(), pos.y())

    def modify_mouse_behavior(self):
        #different mouse handlers
        self.view_box.setMouseMode(self.view_box.RectMode)

        self.pg_layout.scene().sigMouseMoved.connect(self.mouseMoved)
        self.view_box.mouseClickEvent = self.myMouseClickEvent
        self.view_box.mouseDragEvent = self.myMouseDragEvent
        self.view_box.mouseDoubleClickEvent = self.myMouseDoubleClickEvent
        self.view_box.wheelEvent = self.myWheelEvent

    def myMouseClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton or \
                (ev.button() == QtCore.Qt.LeftButton and \
                             ev.modifiers() & QtCore.Qt.ControlModifier):
            view_range = np.array(self.view_box.viewRange()) * 2
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            if (view_range[0][1] - view_range[0][0]) > x_range:
                self._auto_range = True
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
            else:
                self._auto_range = False
                self.view_box.scaleBy(2)
            self.view_box.sigRangeChangedManually.emit(
                self.view_box.state['mouseEnabled'])
        elif ev.button() == QtCore.Qt.LeftButton:
            pos = self.view_box.mapFromScene(ev.pos())
            pos = self.plot_item.mapFromScene(2 * ev.pos() - pos)
            x = pos.x()
            y = pos.y()
            self.mouse_left_clicked.emit(x, y)

    def myMouseDoubleClickEvent(self, ev):
        if (ev.button() == QtCore.Qt.RightButton) or (ev.button() == QtCore.Qt.LeftButton and \
                                                                  ev.modifiers() & QtCore.Qt.ControlModifier):
            self.view_box.autoRange()
            self.view_box.enableAutoRange()
            self._auto_range = True
            self.view_box.sigRangeChangedManually.emit(
                self.view_box.state['mouseEnabled'])

    def myMouseDragEvent(self, ev, axis=None):
        #most of this code is copied behavior of left click mouse drag from the original code
        ev.accept()
        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif *= -1

        if ev.button() == QtCore.Qt.RightButton or \
                (ev.button() == QtCore.Qt.LeftButton and \
                             ev.modifiers() & QtCore.Qt.ControlModifier):
            #determine the amount of translation
            tr = dif
            tr = self.view_box.mapToView(tr) - self.view_box.mapToView(
                pg.Point(0, 0))
            x = tr.x()
            y = tr.y()

            self.view_box.translateBy(x=x, y=y)
        else:
            self._auto_range = False
            pg.ViewBox.mouseDragEvent(self.view_box, ev)

        self.view_box.sigRangeChangedManually.emit(
            self.view_box.state['mouseEnabled'])

    def myWheelEvent(self, ev, axis=None, *args):
        if ev.delta() > 0:
            pg.ViewBox.wheelEvent(self.view_box, ev, axis)

            self._auto_range = False
            # axis_range = self.spectrum_plot.viewRange()
            # self.range_changed.emit(axis_range)
        else:
            view_range = np.array(self.view_box.viewRange())
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and \
                            (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
                self._auto_range = True
            else:
                self._auto_range = False
                pg.ViewBox.wheelEvent(self.view_box, ev)
        self.view_box.sigRangeChangedManually.emit(
            self.view_box.state['mouseEnabled'])
Example #6
0
 def create_graphics(self):
     self.spectrum_plot = self.pg_layout.addPlot(labels={"left": "Intensity", "bottom": "2 Theta"})
     self.spectrum_plot.setLabel("bottom", u"2θ", u"°")
     self.view_box = self.spectrum_plot.vb
     self.legend = LegendItem(horSpacing=20, box=False)
     self.phases_legend = LegendItem(horSpacing=20, box=False)
Example #7
0
class SpectrumView(object):
    def __init__(self, pg_layout):
        self.pg_layout = pg_layout
        self.create_graphics()
        self.create_main_plot()
        self.create_pos_line()
        self.modify_mouse_behavior()
        self.phases = []
        self.overlays = []
        self.overlay_names = []
        self.overlay_show = []
        self.mouse_move_observer = []
        self.left_click_observer = []

    def add_left_click_observer(self, function):
        self.left_click_observer.append(function)

    def add_mouse_move_observer(self, function):
        self.mouse_move_observer.append(function)

    def create_graphics(self):
        self.spectrum_plot = self.pg_layout.addPlot(labels={"left": "Intensity", "bottom": "2 Theta"})
        self.spectrum_plot.setLabel("bottom", u"2θ", u"°")
        self.view_box = self.spectrum_plot.vb
        self.legend = LegendItem(horSpacing=20, box=False)
        self.phases_legend = LegendItem(horSpacing=20, box=False)

    def create_main_plot(self):
        self.plot_item = pg.PlotDataItem(
            np.linspace(0, 10), np.sin(np.linspace(10, 3)), pen=pg.mkPen(color=(255, 255, 255), width=2)
        )
        self.spectrum_plot.addItem(self.plot_item)
        self.legend.addItem(self.plot_item, "")
        self.plot_name = ""
        self.legend.setParentItem(self.spectrum_plot.vb)
        self.legend.anchor(itemPos=(1, 0), parentPos=(1, 0), offset=(-10, -10))
        self.phases_legend.setParentItem(self.spectrum_plot.vb)
        self.phases_legend.anchor(itemPos=(0, 0), parentPos=(0, 0), offset=(0, -10))

    def create_pos_line(self):
        self.pos_line = pg.InfiniteLine(pen=pg.mkPen(color=(0, 255, 0), width=2))
        self.spectrum_plot.addItem(self.pos_line)

    def set_pos_line(self, x):
        self.pos_line.setPos(x)

    def plot_data(self, x, y, name=None):
        self.plot_item.setData(x, y)
        if name is not None:
            self.legend.legendItems[0][1].setText(name)
            self.plot_name = name

    def add_overlay(self, spectrum, show=True):
        x, y = spectrum.data
        color = calculate_color(len(self.overlays) + 1)
        self.overlays.append(pg.PlotDataItem(x, y, pen=pg.mkPen(color=color, width=1.5)))
        self.overlay_names.append(spectrum.name)
        self.overlay_show.append(True)
        if show:
            self.spectrum_plot.addItem(self.overlays[-1])
            self.legend.addItem(self.overlays[-1], spectrum.name)

    def del_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlays.remove(self.overlays[ind])
        self.overlay_names.remove(self.overlay_names[ind])
        self.overlay_show.remove(self.overlay_show[ind])

    def hide_overlay(self, ind):
        self.spectrum_plot.removeItem(self.overlays[ind])
        self.legend.removeItem(self.overlays[ind])
        self.overlay_show[ind] = False

    def show_overlay(self, ind):
        self.spectrum_plot.addItem(self.overlays[ind])
        self.legend.addItem(self.overlays[ind], self.overlay_names[ind])
        self.overlay_show[ind] = True

    def update_overlay(self, spectrum, ind):
        x, y = spectrum.data
        self.overlays[ind].setData(x, y)

    def add_phase(self, name, positions, intensities, baseline):
        self.phases.append(PhasePlot(self.spectrum_plot, self.phases_legend, positions, intensities, name, baseline))

    def update_phase(self, ind, positions, intensities, name=None, baseline=0):
        self.phases[ind].create_items(positions, intensities, name, baseline)

    def update_phase_intensities(self, ind, positions, intensities, baseline=0):
        if len(self.phases):
            self.phases[ind].update_intensities(positions, intensities, baseline)

    def del_phase(self, ind):
        self.phases[ind].remove()
        self.phases.remove(self.phases[ind])

    def plot_vertical_lines(self, positions, phase_index=0, name=None):
        if len(self.phases) <= phase_index:
            self.phases.append(PhaseLinesPlot(self.spectrum_plot, positions))
        else:
            self.phases[phase_index].set_data(positions, name)

    def mouseMoved(self, pos):
        pos = self.plot_item.mapFromScene(pos)
        for function in self.mouse_move_observer:
            function(pos.x(), pos.y())

    def modify_mouse_behavior(self):
        # different mouse handlers
        self.view_box.setMouseMode(self.view_box.RectMode)

        self.pg_layout.scene().sigMouseMoved.connect(self.mouseMoved)
        self.view_box.mouseClickEvent = self.myMouseClickEvent
        self.view_box.mouseDragEvent = self.myMouseDragEvent
        self.view_box.mouseDoubleClickEvent = self.myMouseDoubleClickEvent
        self.view_box.wheelEvent = self.myWheelEvent

    def myMouseClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton:
            view_range = np.array(self.view_box.viewRange()) * 2
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
                self.view_box.enableAutoRange()
            else:
                self.view_box.scaleBy(2)
        if ev.button() == QtCore.Qt.LeftButton:
            pos = self.view_box.mapFromScene(ev.pos())
            pos = self.plot_item.mapFromScene(2 * ev.pos() - pos)
            x = pos.x()
            y = pos.y()
            for function in self.left_click_observer:
                function(x, y)

    def myMouseDoubleClickEvent(self, ev):
        if ev.button() == QtCore.Qt.RightButton:
            self.view_box.autoRange()
            self.view_box.enableAutoRange()

    def myMouseDragEvent(self, ev, axis=None):
        # most of this code is copied behavior of left click mouse drag from the original code
        ev.accept()
        pos = ev.pos()
        lastPos = ev.lastPos()
        dif = pos - lastPos
        dif *= -1
        ## Ignore axes if mouse is disabled
        mouseEnabled = np.array(self.view_box.state["mouseEnabled"], dtype=np.float)
        mask = mouseEnabled.copy()
        if axis is not None:
            mask[1 - axis] = 0.0

        if ev.button() == QtCore.Qt.RightButton:
            # determine the amount of translation
            tr = dif * mask
            tr = self.view_box.mapToView(tr) - self.view_box.mapToView(pg.Point(0, 0))
            x = tr.x()
            y = tr.y()

            self.view_box.translateBy(x=x, y=y)
            self.view_box.sigRangeChangedManually.emit(self.view_box.state["mouseEnabled"])
        else:
            pg.ViewBox.mouseDragEvent(self.view_box, ev)

    def myWheelEvent(self, ev):
        if ev.delta() > 0:
            pg.ViewBox.wheelEvent(self.view_box, ev)
        else:
            view_range = np.array(self.view_box.viewRange())
            curve_data = self.plot_item.getData()
            x_range = np.max(curve_data[0]) - np.min(curve_data[0])
            y_range = np.max(curve_data[1]) - np.min(curve_data[1])
            if (view_range[0][1] - view_range[0][0]) > x_range and (view_range[1][1] - view_range[1][0]) > y_range:
                self.view_box.autoRange()
            else:
                pg.ViewBox.wheelEvent(self.view_box, ev)