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)
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)
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)
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'])
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'])
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)
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)