class ImageAnalysisViewBox(pg.ViewBox): """ Custom ViewBox used to over-ride the context menu. I don't want the full context menu, just a view all and an export. Export does not call a dialog, just prompts user for filename. """ def __init__(self,parent=None,border=None,lockAspect=False,enableMouse=True,invertY=False,enableMenu=True,name=None): pg.ViewBox.__init__(self,parent,border,lockAspect,enableMouse,invertY,enableMenu,name) self.menu = None # Override pyqtgraph ViewBoxMenu self.menu = self.getMenu(None) def raiseContextMenu(self, ev): if not self.menuEnabled(): return menu = self.getMenu(ev) pos = ev.screenPos() menu.popup(QtCore.QPoint(pos.x(), pos.y())) def export(self): self.exp = ImageExporter(self) self.exp.export() def getMenu(self,event): if self.menu is None: self.menu = QtGui.QMenu() self.viewAll = QtGui.QAction("View All", self.menu) self.exportImage = QtGui.QAction("Export image", self.menu) self.viewAll.triggered[()].connect(self.autoRange) self.exportImage.triggered[()].connect(self.export) self.menu.addAction(self.viewAll) self.menu.addAction(self.exportImage) return self.menu
def save_plot(self): from PySide2.QtWidgets import QFileDialog (fileName, selectedFilter) = QFileDialog.getSaveFileName( None, "Open Image", path.expanduser("~"), "Image Files (*.png *.jpg *.bmp)") if fileName: from pyqtgraph.exporters import ImageExporter exporter = ImageExporter(self.fftGraphicsView.plotItem) exporter.export(fileName)
def export(self, fname, export_type="image"): """ Save the item as an image """ if export_type == "image": exporter = ImageExporter(self.scene()) elif export_type == "svg": exporter = SVGExporter(self.scene()) exporter.export(fname) del exporter
def test_ImageExporter_toBytes(): p = pg.plot() p.hideAxis('bottom') p.hideAxis('left') exp = ImageExporter(p.getPlotItem()) qimg = exp.export(toBytes=True) qimg = qimg.convertToFormat(QtGui.QImage.Format.Format_RGBA8888) data = fn.qimage_to_ndarray(qimg) black = (0, 0, 0, 255) assert np.all(data == black), "Exported image should be entirely black."
def __init__(self, parent, name, plot, statusbar=None): super(SaveChartDialog, self).__init__(parent) self.setupUi(self) self.name = name self.plot = plot self.exporter = ImageExporter(self.plot.getPlotItem()) self.__x = self.plot.size().width() self.__y = self.plot.size().height() self.__aspectRatio = self.__x / self.__y self.widthPixels.setValue(self.__x) self.heightPixels.setValue(self.__y) self.statusbar = statusbar self.__dialog = QFileDialog(parent=self)
def export_plot(plt, filename, width=None, height=None): """ Export an existing plot to an image and save with given filename. Optionally, image width and height in pixels can be specified. """ e = ImageExporter(plt.plotItem) if width is not None: e.parameters()['width'] = width if height is not None: e.parameters()['height'] = height e.export(filename)
class SaveChartDialog(QDialog, Ui_saveChartDialog): ''' Save Chart dialog ''' def __init__(self, parent, name, plot, statusbar=None): super(SaveChartDialog, self).__init__(parent) self.setupUi(self) self.name = name self.plot = plot self.exporter = ImageExporter(self.plot.getPlotItem()) self.__x = self.plot.size().width() self.__y = self.plot.size().height() self.__aspectRatio = self.__x / self.__y self.widthPixels.setValue(self.__x) self.heightPixels.setValue(self.__y) self.statusbar = statusbar self.__dialog = QFileDialog(parent=self) def accept(self): formats = "Portable Network Graphic (*.png)" file_name = self.__dialog.getSaveFileName(self, 'Export Chart', f"{self.name}.png", formats) if file_name: output_file = str(file_name[0]).strip() if len(output_file) == 0: return else: self.exporter.parameters()['width'] = self.widthPixels.value() self.__force_to_int('height') self.__force_to_int('width') self.exporter.export(output_file) if self.statusbar is not None: self.statusbar.showMessage( f"Saved {self.name} to {output_file}", 5000) QDialog.accept(self) def __force_to_int(self, param_name): h = self.exporter.params.param(param_name) orig_h = int(self.exporter.parameters()[param_name]) with block_signals(h): h.setValue(orig_h + 0.1) h.setValue(orig_h) def set_height(self, newWidth): ''' Updates the height as the width changes according to the aspect ratio. :param newWidth: the new width. ''' self.heightPixels.setValue( int(math.floor(newWidth / self.__aspectRatio)))
def _repr_png_(self): self.show() self.hide() if not self.btn.visible: display(self.btn) self.btn.visible = True mainExp = ImageExporter(self.plotItem) self.image = mainExp.export(toBytes=True) byte_array = QByteArray() buffer = QBuffer(byte_array) buffer.open(QIODevice.ReadWrite) self.image.save(buffer, 'PNG') buffer.close() return bytes(byte_array)
def saveFig(): # Get pix map of window and save png dirName = "/home" fname = "sampleWindow.png" fname2 = "samplePlotWindow.png" dataPath = dirName + fname dataPath2 = dirName + fname2 locObj = QtGui.QPixmap.grabWindow(glw.winId()) locObj.save(dataPath, 'png') exporter = IE.ImageExporter(plt) exporter.export(dataPath2)
def draw_image(self, index, color, x, y, split_name_list): self.plt.plot(x, y, pen=pg.mkPen(QColor(color[0], color[1], color[2]))) pltItem = self.plt.getPlotItem() left_axis = pltItem.getAxis("left") left_axis.enableAutoSIPrefix(False) font = QFont() font.setPixelSize(16) left_axis.tickFont = font bottom_axis = pltItem.getAxis("bottom") bottom_axis.tickFont = font exporter = ImageExporter(self.plt.getPlotItem()) exporter.parameters()['width'] = 800 exporter.parameters()['height'] = 600 split_name = 'tmp/' + 'split_' + str(index) + '.png' exporter.export(split_name) split_name_list.append(split_name)
class PlotWidget(DockArea): instance = None n_spectra = 20 def __init__(self, set_coordinate_func=None, parent=None): pg.setConfigOption('background', 'w') pg.setConfigOption('foreground', 'k') pg.setConfigOptions(antialias=True) super(PlotWidget, self).__init__(parent) PlotWidget.instance = self self.set_coordinate_func = set_coordinate_func self.change_range_lock = False self.smooth_count = 0 self.fit_matrix = None self.matrix = None self.matrix_min = None self.matrix_max = None self.trace_plot_item = None self.spectrum_plot_item = None self.trace_plot_item_fit = None self.spectrum_plot_item_fit = None self.trace_orig_plot_item = None self.spectrum_orig_plot_item = None self.heat_map_levels = None self.selected_range_idxs = None # heat map self.heat_map_dock = Dock("Heat Map", size=(50, 7)) self.heat_map_plot = HeatMapPlot(title="Heat Map") self.heat_map_plot.range_changed.connect(self.heat_map_range_changed) # # updates the spectra when y range of heatmap was changed # self.heat_map_plot.Y_range_changed.connect(self.update_spectra) self.heat_map_plot.levels_changed.connect(self.heat_map_levels_changed) heatmap_w = pg.GraphicsLayoutWidget() heatmap_w.ci.addItem(self.heat_map_plot) self.heat_map_dock.addWidget(heatmap_w) # self.ci.addItem(self.heat_map_plot) self.heat_map_vline = pg.InfiniteLine(angle=90, movable=True, pen=pg.mkPen((0, 0, 0))) self.heat_map_hline = pg.InfiniteLine(angle=0, movable=True, pen=pg.mkPen((0, 0, 0))) self.heat_map_plot.heat_map_plot.addItem(self.heat_map_vline, ignoreBounds=True) self.heat_map_plot.heat_map_plot.addItem(self.heat_map_hline, ignoreBounds=True) # self.spectra_plot = self.ci.addPlot(title="Spectra") # Spectra plot w_spectra = pg.PlotWidget(title="Spectra") self.spectra_plot = w_spectra.plotItem self.spectra_vline = pg.InfiniteLine(angle=90, movable=True, pen=pg.mkPen((0, 0, 0))) self.spectra_plot.addItem(self.spectra_vline, ignoreBounds=True) self.spectra_plot.showAxis('top', show=True) self.spectra_plot.showAxis('right', show=True) self.spectra_plot.setLabel('left', text='\u0394A') self.spectra_plot.setLabel('bottom', text='Wavelength (nm)') self.spectra_plot.showGrid(x=True, y=True, alpha=0.1) self.spectra_dock = Dock("Spectra", widget=w_spectra, size=(40, 7)) # Spectrum plot w_spectrum = pg.PlotWidget(title="Spectrum") self.spectrum = w_spectrum.plotItem self.spectrum_vline = pg.InfiniteLine(angle=90, movable=True, pen=pg.mkPen('b')) self.spectrum.addItem(self.spectrum_vline, ignoreBounds=True) self.spectrum.showAxis('top', show=True) self.spectrum.showAxis('right', show=True) self.spectrum.setLabel('left', text='\u0394A') self.spectrum.setLabel('bottom', text='Wavelength (nm)') self.spectrum_dock = Dock("Spectrum", widget=w_spectrum) self.spectrum.getViewBox().sigRangeChanged.connect( self.trace_spectrum_range_changed) # Trace plot w_trace = pg.PlotWidget(title="Trace") self.trace = w_trace.plotItem # self.trace = self.ci.addPlot(title="Trace") self.trace_vline = pg.InfiniteLine(angle=90, movable=True, pen=pg.mkPen('b')) self.trace.addItem(self.trace_vline, ignoreBounds=True) self.trace.showAxis('top', show=True) self.trace.showAxis('right', show=True) self.trace.setLabel('left', text='\u0394A') self.trace.setLabel('bottom', text='Time (us)') self.spectrum.showGrid(x=True, y=True, alpha=0.1) self.trace.showGrid(x=True, y=True, alpha=0.1) self.trace_dock = Dock("Trace", widget=w_trace) self.trace.getViewBox().sigRangeChanged.connect( self.trace_spectrum_range_changed) # data panel self.data_panel = DataPanel() self.settings_dock = Dock("Properties", widget=self.data_panel, size=(1, 1)) self.data_panel.txb_t0.focus_lost.connect(self.update_range) self.data_panel.txb_t0.returnPressed.connect(self.update_range) self.data_panel.txb_t1.focus_lost.connect(self.update_range) self.data_panel.txb_t1.returnPressed.connect(self.update_range) self.data_panel.txb_w0.focus_lost.connect(self.update_range) self.data_panel.txb_w0.returnPressed.connect(self.update_range) self.data_panel.txb_w1.focus_lost.connect(self.update_range) self.data_panel.txb_w1.returnPressed.connect(self.update_range) self.data_panel.txb_z0.focus_lost.connect(self.update_levels) self.data_panel.txb_z0.returnPressed.connect(self.update_levels) self.data_panel.txb_z1.focus_lost.connect(self.update_levels) self.data_panel.txb_z1.returnPressed.connect(self.update_levels) self.data_panel.txb_n_spectra.setText(str(self.n_spectra)) self.data_panel.btn_crop_matrix.clicked.connect( self.btn_crop_matrix_clicked) self.data_panel.btn_restore_matrix.clicked.connect( self.btn_restore_matrix_clicked) self.data_panel.txb_n_spectra.focus_lost.connect( self.txb_n_spectra_focus_lost) self.data_panel.txb_n_spectra.returnPressed.connect( self.txb_n_spectra_focus_lost) self.data_panel.btn_redraw_spectra.clicked.connect(self.update_spectra) self.data_panel.txb_SVD_filter.focus_lost.connect( self.txb_SVD_filter_changed) self.data_panel.txb_SVD_filter.returnPressed.connect( self.txb_SVD_filter_changed) self.data_panel.cb_SVD_filter.toggled.connect( self.cb_SVD_filter_toggled) self.data_panel.txb_ICA_filter.focus_lost.connect( self.txb_ICA_filter_changed) self.data_panel.txb_ICA_filter.returnPressed.connect( self.txb_ICA_filter_changed) self.data_panel.cb_ICA_filter.toggled.connect( self.cb_ICA_filter_toggled) self.data_panel.btn_center_levels.clicked.connect( self.btn_center_levels_clicked) self.data_panel.txb_SVD_filter.setText("1-5") self.data_panel.btn_fit_chirp_params.clicked.connect( self.fit_chirp_params) self.data_panel.cb_show_chirp_points.toggled.connect( self.cb_show_roi_checkstate_changed) # addition of docs self.addDock(self.heat_map_dock, 'left') self.addDock(self.spectra_dock, 'right') self.addDock(self.spectrum_dock, 'bottom') self.addDock(self.trace_dock, 'right', self.spectrum_dock) self.addDock(self.settings_dock, 'left', self.heat_map_dock) def update_v_lines(): time_pos = self.heat_map_hline.pos() wl_pos = self.heat_map_vline.pos() new_pos = self.heat_map_plot.transform_wl_pos(wl_pos[0]) self.spectrum_vline.setPos(new_pos) self.spectra_vline.setPos(new_pos) self.trace_vline.setPos( self.heat_map_plot.transform_t_pos(time_pos[1])) def update_heat_lines(): time_pos = self.trace_vline.pos() wl_pos = self.spectrum_vline.pos() self.heat_map_hline.setPos( self.heat_map_plot.inv_transform_t_pos(time_pos[0])) # self.heat_map_vline.setPos(wl_pos[0]) self.heat_map_vline.setPos( self.heat_map_plot.inv_transform_wl_pos(wl_pos[0])) def update_heat_lines_spectra(): wl_pos = self.spectra_vline.pos() self.heat_map_vline.setPos( self.heat_map_plot.inv_transform_wl_pos(wl_pos[0])) self.heat_map_vline.sigPositionChanged.connect(update_v_lines) self.heat_map_hline.sigPositionChanged.connect(update_v_lines) self.spectrum_vline.sigPositionChanged.connect(update_heat_lines) self.spectra_vline.sigPositionChanged.connect( update_heat_lines_spectra) self.trace_vline.sigPositionChanged.connect(update_heat_lines) self.heat_map_vline.sigPositionChanged.connect( self.update_trace_and_spectrum) self.heat_map_hline.sigPositionChanged.connect( self.update_trace_and_spectrum) self.spectrum_vline.sigPositionChanged.connect( self.update_trace_and_spectrum) self.spectra_vline.sigPositionChanged.connect( self.update_trace_and_spectrum) self.trace_vline.sigPositionChanged.connect( self.update_trace_and_spectrum) self.roi = None self.chirp = self.heat_map_plot.heat_map_plot.plot([]) # self.heat_map_vline.sigPositionChangeFinished.connect(self.update_trace_and_spectrum) # self.heat_map_hline.sigPositionChangeFinished.connect(self.update_trace_and_spectrum) # self.spectrum_vline.sigPositionChangeFinished.connect(self.update_trace_and_spectrum) # self.trace_vline.sigPositionChangeFinished.connect(self.update_trace_and_spectrum) def get_roi_pos(self): """This shit took me half a day to figure out.""" if self.roi is None: return hs = self.roi.getHandles() n = len(hs) positions = np.zeros((n, 2)) for i, h in enumerate(self.roi.getHandles()): qPoint = self.roi.mapSceneToParent(h.scenePos()) positions[i, 0] = self.heat_map_plot.transform_wl_pos(qPoint.x()) positions[i, 1] = self.heat_map_plot.transform_t_pos(qPoint.y()) return positions def cb_show_roi_checkstate_changed(self): if self.roi is None: return val = 1000 if self.data_panel.cb_show_chirp_points.isChecked( ) else -1000 self.roi.setZValue(val) def plot_chirp_points(self): if self.roi is None: t_mid = (self.matrix.times[-1] - self.matrix.times[0]) / 2 n_w = self.matrix.wavelengths.shape[0] - 1 wls = self.matrix.wavelengths[int(n_w / 5)], self.matrix.wavelengths[int(2 * n_w / 5)], \ self.matrix.wavelengths[int(3 * n_w / 5)], self.matrix.wavelengths[int(4 * n_w / 5)] self.roi = pg.PolyLineROI([[wls[0], t_mid], [wls[1], t_mid], [wls[2], t_mid], [wls[3], t_mid]], closed=False, handlePen=pg.mkPen(color=(0, 255, 0), width=5), hoverPen=pg.mkPen(color=(0, 150, 0), width=2), handleHoverPen=pg.mkPen(color=(0, 150, 0), width=3)) self.heat_map_plot.heat_map_plot.addItem(self.roi) def add_chirp(self, wls, mu): # plots the chirp pen = pg.mkPen(color=QColor('black'), width=2) mu_tr = self.heat_map_plot.inv_transform_t_pos(mu) wls_tr = self.heat_map_plot.inv_transform_wl_pos(wls) self.chirp.setData(wls_tr, mu_tr, pen=pen) def fit_chirp_params(self): from Widgets.fit_widget import FitWidget as _fw if _fw.instance is None: return fw = _fw.instance if fw.current_model._class != 'Femto': return roi_pos = self.get_roi_pos() x, y = roi_pos[:, 0], roi_pos[:, 1] lambda_c = fw.current_model.get_lambda_c() if fw.current_model.chirp_type == 'exp': mul, lam = fit_sum_exp(x - lambda_c, y, fw.current_model.n_exp_chirp, fit_intercept=True) parmu = [mul[-1]] + [ entry for tup in zip(mul[:-1], lam[:-1]) for entry in tup ] fw.current_model.set_parmu(parmu, 'exp') else: n = fw.current_model.n_poly_chirp + 1 parmu = fit_polynomial_coefs(x - lambda_c, y, n) fw.current_model.set_parmu(parmu, 'poly') fw.update_model_par_count(update_after_fit=True) def use_mask(self): if self.matrix is None: return self.matrix.Mask = not self.matrix.Mask self.plot_matrix(self.matrix, center_lines=False, keep_range=True, keep_fits=True) def cb_SVD_filter_toggled(self): if self.matrix is None: return self.matrix.SVD_filter = self.data_panel.cb_SVD_filter.isChecked() # self.plot_matrix(self.matrix, center_lines=False, keep_range=True) if self.data_panel.cb_SVD_filter.isChecked(): self.txb_SVD_filter_changed() else: self.plot_matrix(self.matrix, center_lines=False, keep_range=True, keep_fits=True) def cb_ICA_filter_toggled(self): if self.matrix is None: return self.matrix.ICA_filter = self.data_panel.cb_ICA_filter.isChecked() if self.data_panel.cb_ICA_filter.isChecked(): self.txb_ICA_filter_changed() else: self.plot_matrix(self.matrix, center_lines=False, keep_range=True, keep_fits=True) def txb_ICA_filter_changed(self): if self.matrix is None: return r_text = self.data_panel.txb_ICA_filter.text() vals = list(filter( None, r_text.split(','))) # splits by comma and removes empty entries int_vals = [] for val in vals: try: if str_is_integer(val): int_vals.append(int(val) - 1) else: # we dont have a single number, but in a format of eg. '1-3' if '-' not in val: continue split = val.split('-') x0 = int(split[0]) x1 = int(split[1]) int_vals += [i - 1 for i in range(x0, x1 + 1)] except: continue n_comp = int(SVDWidget.instance.data_panel.sb_n_ICA.value()) result = sorted(list(filter(lambda item: 0 <= item < n_comp, int_vals))) self.matrix.set_ICA_filter(result, n_components=n_comp) if self.data_panel.cb_ICA_filter.isChecked(): self.plot_matrix(self.matrix, center_lines=False, keep_range=True, keep_fits=True) def txb_SVD_filter_changed(self): if self.matrix is None: return r_text = self.data_panel.txb_SVD_filter.text() # format - values separated by comma, eg. '1, 2, 3', '1-4, -3' vals = list(filter( None, r_text.split(','))) # splits by comma and removes empty entries int_vals = [] remove_vals = [] for val in vals: try: if str_is_integer(val): int_val = int(val) if int_val > 0: int_vals.append(int_val - 1) else: remove_vals.append( -1 * int_val - 1 ) #put negative values into different list as positives else: # we dont have a single number, but in a format of eg. '1-3' if '-' not in val: continue split = val.split('-') x0 = int(split[0]) x1 = int(split[1]) int_vals += [i - 1 for i in range(x0, x1 + 1)] except: continue result = sorted(list(set(int_vals) - set(remove_vals))) if not (result is None or len(result) == 0): self.matrix.set_SVD_filter(result) if self.data_panel.cb_SVD_filter.isChecked(): self.plot_matrix(self.matrix, center_lines=False, keep_range=True, keep_fits=True) def txb_n_spectra_focus_lost(self): try: n = int(self.data_panel.txb_n_spectra.text()) self.n_spectra = max(2, n) self.data_panel.txb_n_spectra.setText(str(self.n_spectra)) self.update_spectra() except ValueError: pass def trace_spectrum_range_changed(self, vb, range): if self.change_range_lock: return self.change_range_lock = True if vb == self.spectrum.getViewBox(): w0 = self.heat_map_plot.inv_transform_wl_pos(range[0][0]) w1 = self.heat_map_plot.inv_transform_wl_pos(range[0][1]) self.heat_map_plot.heat_map_plot.getViewBox().setXRange(w0, w1, padding=0) self.set_txb_ranges(w0=range[0][0], w1=range[0][1]) else: t0 = self.heat_map_plot.inv_transform_t_pos(range[0][0]) t1 = self.heat_map_plot.inv_transform_t_pos(range[0][1]) self.heat_map_plot.heat_map_plot.getViewBox().setYRange(t0, t1, padding=0) self.set_txb_ranges(t0=range[0][0], t1=range[0][1]) self.change_range_lock = False def get_selected_range(self): if self.matrix is None: return try: t0, t1 = float(self.data_panel.txb_t0.text()), float( self.data_panel.txb_t1.text()) w0, w1 = float(self.data_panel.txb_w0.text()), float( self.data_panel.txb_w1.text()) if t0 > t1 or w0 > w1: return except ValueError: return return w0, w1, t0, t1 def set_txb_ranges(self, w0=None, w1=None, t0=None, t1=None): if w0 is not None: self.data_panel.txb_w0.setText(f'{w0:.4g}') if w1 is not None: self.data_panel.txb_w1.setText(f'{w1:.4g}') if t0 is not None: self.data_panel.txb_t0.setText(f'{t0:.4g}') if t1 is not None: self.data_panel.txb_t1.setText(f'{t1:.4g}') def heat_map_range_changed(self, vb, range): if self.change_range_lock or self.matrix is None: return self.change_range_lock = True w0, w1, t0, t1 = range[0][0], range[0][1], range[1][0], range[1][1] t0 = self.heat_map_plot.transform_t_pos(t0) # transform t positions t1 = self.heat_map_plot.transform_t_pos(t1) w0 = self.heat_map_plot.transform_wl_pos(w0) # transform t positions w1 = self.heat_map_plot.transform_wl_pos(w1) self.set_txb_ranges(w0, w1, t0, t1) self.spectrum.getViewBox().setXRange(w0, w1, padding=0) self.trace.getViewBox().setXRange(t0, t1, padding=0) # keep all the v and h lines inside the visible area v_pos = self.heat_map_vline.pos()[0] h_pos = self.heat_map_hline.pos()[1] if not range[0][0] <= v_pos <= range[0][1]: self.heat_map_vline.setPos(range[0][0] if np.abs( v_pos - range[0][0]) < np.abs(v_pos - range[0][1]) else range[0][1]) if not range[1][0] <= h_pos <= range[1][1]: self.heat_map_hline.setPos(range[1][0] if np.abs( h_pos - range[1][0]) < np.abs(h_pos - range[1][1]) else range[1][1]) it0, it1 = find_nearest_idx( self.matrix.times, t0), find_nearest_idx(self.matrix.times, t1) + 1 iw0, iw1 = find_nearest_idx( self.matrix.wavelengths, w0), find_nearest_idx(self.matrix.wavelengths, w1) + 1 self.selected_range_idxs = (it0, it1, iw0, iw1) self.data_panel.lbl_visible_area_msize.setText( f'{it1 - it0} x {iw1 - iw0}') self.change_range_lock = False def heat_map_levels_changed(self, hist): z_levels = self.heat_map_plot.get_z_range() self.data_panel.txb_z0.setText(f'{z_levels[0]:.4g}') self.data_panel.txb_z1.setText(f'{z_levels[1]:.4g}') def update_range(self): if self.change_range_lock or self.matrix is None: return try: t0, t1 = float(self.data_panel.txb_t0.text()), float( self.data_panel.txb_t1.text()) w0, w1 = float(self.data_panel.txb_w0.text()), float( self.data_panel.txb_w1.text()) if t0 <= t1 and w0 <= w1: self.heat_map_plot.set_xy_range(w0, w1, t0, t1, 0) except ValueError: pass except AttributeError: pass def update_levels(self): try: z0, z1 = float(self.data_panel.txb_z0.text()), float( self.data_panel.txb_z1.text()) if z0 <= z1: self.heat_map_plot.hist.setLevels(z0, z1) except ValueError: pass def btn_center_levels_clicked(self): z0, z1 = self.heat_map_plot.get_z_range() diff = z1 - z0 self.heat_map_plot.hist.setLevels(-diff / 2, diff / 2) def btn_crop_matrix_clicked(self): if self.matrix is None: return w0, w1, t0, t1 = self.get_selected_range() self.matrix.crop_data(t0, t1, w0, w1) SVDWidget.instance.set_data(self.matrix) self.cb_SVD_filter_toggled() # self.plot_matrix(self.matrix, False) def crop_matrix(self, t0=None, t1=None, w0=None, w1=None): if self.matrix is None: return self.matrix.crop_data(t0, t1, w0, w1) SVDWidget.instance.set_data(self.matrix) self.cb_SVD_filter_toggled() def baseline_correct(self, t0=0, t1=0.2): if self.matrix is None: return self.matrix.baseline_corr(t0, t1) SVDWidget.instance.set_data(self.matrix) self.cb_SVD_filter_toggled() def dimension_mul(self, t_mul=1, w_mul=1): if self.matrix is None: return self.matrix.times *= t_mul self.matrix.wavelengths *= w_mul SVDWidget.instance.set_data(self.matrix) self.cb_SVD_filter_toggled() def btn_restore_matrix_clicked(self): if self.matrix is None: return self.matrix.restore_original_data() self.plot_matrix(self.matrix, False) def init_trace_and_spectrum(self): self.trace_plot_item = self.trace.plot([]) self.spectrum_plot_item = self.spectrum.plot([]) self.trace_orig_plot_item = self.trace.plot([]) self.spectrum_orig_plot_item = self.spectrum.plot([]) def init_fit_trace_sp(self): self.trace_plot_item_fit = self.trace.plot([]) self.spectrum_plot_item_fit = self.spectrum.plot([]) def update_trace_and_spectrum(self): # pass if self.matrix is None: return time_pos = self.heat_map_hline.pos()[1] time_pos = self.heat_map_plot.transform_t_pos(time_pos) wl_pos = self.heat_map_vline.pos()[0] wl_pos = self.heat_map_plot.transform_wl_pos(wl_pos) wavelengths = self.matrix.wavelengths times = self.matrix.times t_idx = find_nearest_idx(times, time_pos) wl_idx = find_nearest_idx(wavelengths, wl_pos) trace_y_data = self.matrix.D[:, wl_idx] trace_y_datorig = self.matrix.Y[:, wl_idx] pen = pg.mkPen(color=QColor('black'), width=1) pen_orig_data = pg.mkPen(color=QColor('blue'), width=1) spectrum_y_data = self.matrix.D[t_idx, :] spectrum_y_data_orig = self.matrix.Y[t_idx, :] # if self.smooth_count == 0: # spectrum_y_data = self.matrix.D[t_idx, :] # spectrum_y_data_orig = self.matrix.Y[t_idx, :] # else: # avrg_slice_matrix = self.matrix.D[t_idx - self.smooth_count:t_idx + self.smooth_count, :] # spectrum_y_data = np.average(avrg_slice_matrix, axis=0) if self.trace_plot_item is not None: self.trace_plot_item.setData(times, trace_y_data, pen=pen) self.spectrum_plot_item.setData(wavelengths, spectrum_y_data, pen=pen) if not np.allclose(trace_y_data, trace_y_datorig): self.trace_orig_plot_item.setData(times, trace_y_datorig, pen=pen_orig_data) self.spectrum_orig_plot_item.setData(wavelengths, spectrum_y_data_orig, pen=pen_orig_data) else: self.trace_orig_plot_item.setData([]) self.spectrum_orig_plot_item.setData([]) # plotting fit if self.spectrum_plot_item_fit is not None and self.trace_plot_item_fit is not None and self.fit_matrix is not None: trace_y_data_fit = self.fit_matrix.Y[:, wl_idx] if self.smooth_count == 0: spectrum_y_data_fit = self.fit_matrix.Y[t_idx, :] else: avrg_slice_matrix_fit = self.fit_matrix.Y[ t_idx - self.smooth_count:t_idx + self.smooth_count, :] spectrum_y_data_fit = np.average(avrg_slice_matrix_fit, axis=0) pen_fit = pg.mkPen(color=QColor('red'), width=1) self.trace_plot_item_fit.setData(times, trace_y_data_fit, pen=pen_fit) self.spectrum_plot_item_fit.setData(wavelengths, spectrum_y_data_fit, pen=pen_fit) if self.set_coordinate_func is not None: self.set_coordinate_func('w = {:.5g}, t = {:.5g}'.format( wavelengths[wl_idx], times[t_idx])) # self.spectrum.setTitle("Spectrum, t = {:.3g} us".format(time_pos)) # self.trace.setTitle("Trace, \u03bb = {:.3g} nm".format(wl_pos)) def set_fit_matrix(self, fit_matrix): self.fit_matrix = fit_matrix self.spectrum.clearPlots() self.trace.clearPlots() self.init_trace_and_spectrum() self.init_fit_trace_sp() self.update_trace_and_spectrum() self.spectrum.autoBtnClicked() self.trace.autoBtnClicked() def update_spectra(self): if self.matrix is None: return self.spectra_plot.clearPlots() tup = self.get_selected_range() if tup is None: return w0, w1, t0, t1 = tup D_crop, times, wavelengths = crop_data(self.matrix.D, self.matrix.times, self.matrix.wavelengths, t0, t1, w0, w1) for i in range(self.n_spectra): sp = D_crop[int(i * D_crop.shape[0] / self.n_spectra)] color = pg.intColor(i, hues=self.n_spectra, values=1, maxHue=360, minHue=0) pen = pg.mkPen(color=color, width=1) self.spectra_plot.plot(wavelengths, sp, pen=pen) def plot_matrix(self, matrix, center_lines=True, keep_range=False, keep_fits=False): w_range, t_range = self.heat_map_plot.heat_map_plot.getViewBox( ).viewRange() z_range = self.heat_map_plot.get_z_range() self.spectrum.clearPlots() self.trace.clearPlots() # self.spectra_plot.clearPlots() self.matrix = matrix self.matrix_min = np.min(matrix.D) self.matrix_max = np.max(matrix.D) if self.matrix.original_data_matrix is not None: self.data_panel.lbl_matrix_size.setText( f'{matrix.original_data_matrix.shape[0] - 1} x {matrix.original_data_matrix.shape[1] - 1}' ) self.data_panel.lbl_cr_matrix_size.setText( f'{matrix.D.shape[0]} x {matrix.D.shape[1]}') self.heat_map_plot.set_matrix(matrix.D, matrix.times, matrix.wavelengths, gradient=HeatMapPlot.sym_grad, t_range=t_range if keep_range else None, w_range=w_range if keep_range else None, z_range=z_range if keep_range else None) self.spectrum.getViewBox().setLimits(xMin=matrix.wavelengths[0], xMax=matrix.wavelengths[-1], yMin=self.matrix_min, yMax=self.matrix_max) self.spectra_plot.getViewBox().setLimits(xMin=matrix.wavelengths[0], xMax=matrix.wavelengths[-1], yMin=self.matrix_min, yMax=self.matrix_max) self.trace.getViewBox().setLimits(xMin=matrix.times[0], xMax=matrix.times[-1], yMin=self.matrix_min, yMax=self.matrix_max) self.spectrum_vline.setBounds( [matrix.wavelengths[0], matrix.wavelengths[-1]]) self.spectra_vline.setBounds( [matrix.wavelengths[0], matrix.wavelengths[-1]]) self.trace_vline.setBounds([matrix.times[0], matrix.times[-1]]) self.heat_map_vline.setBounds( [matrix.wavelengths[0], matrix.wavelengths[-1]]) self.heat_map_hline.setBounds([matrix.times[0], matrix.times[-1]]) # autoscale heatmap # self.heat_map_plot.autoBtnClicked() # setupline in the middle of matrix if center_lines: self.heat_map_vline.setPos( (matrix.wavelengths[-1] + matrix.wavelengths[0]) / 2) self.heat_map_hline.setPos( (matrix.times[-1] + matrix.times[0]) / 2) # update their positions self.heat_map_hline.sigPositionChanged.emit(object) # self.hist.gradient.restoreState(self.sym_grad) self.init_trace_and_spectrum() if keep_fits: self.init_fit_trace_sp() # redraw trace and spectrum figures self.update_trace_and_spectrum() self.update_spectra() self.plot_chirp_points() self.cb_show_roi_checkstate_changed() def save_plot_to_clipboard_as_png(self, plot_item): self.img_exporter = ImageExporter(plot_item) self.img_exporter.export(copy=True) def save_plot_to_clipboard_as_svg(self, plot_item): self.svg_exporter = SVGExporter(plot_item) self.svg_exporter.export(copy=True)
def getQImage(self, resX=None,resY=None): #zoom the the chosen colorrange: r = self.ui.histogram.region.getRegion() self.ui.histogram.vb.setYRange(*r) #create ImageExporters: mainExp = ImageExporter(self.view) colorAxisExp = ImageExporter(self.ui.histogram.axis) colorBarExp = ImageExporter(self.ui.histogram.gradient) if resX or resY: #get size-x: mainW = mainExp.getTargetRect().width() colorAxisW = colorAxisExp.getTargetRect().width() colorBarW = colorBarExp.getTargetRect().width() #all parts have the same height: mainExp.parameters()['height'] = resY colorAxisExp.parameters()['height'] = resY colorBarExp.parameters()['height'] = resY #size x is proportional: sumWidth = mainW + colorAxisW + colorBarW mainExp.parameters()['width'] = resX * mainW / sumWidth colorAxisExp.parameters()['width'] = resX * colorAxisW / sumWidth colorBarExp.parameters()['width'] = resX * colorBarW / sumWidth #create QImages: main =mainExp.export(toBytes=True) colorAxis =colorAxisExp.export(toBytes=True) colorBar = colorBarExp.export(toBytes=True) #define the size: x = main.width() + colorAxis.width() + colorBar.width() y = main.height() #to get everything in the same height: yOffs = [0,0.5*(y-colorAxis.height()),0.5*(y-colorBar.height())] result = QtGui.QImage(x, y ,QtGui.QImage.Format_RGB32) #the colorbar is a bit smaller that the rest. to exclude black lines paint all white: result.fill(QtCore.Qt.white) painter = QtGui.QPainter(result) posX = 0 for img,y in zip((main,colorAxis,colorBar),yOffs): #draw every part in different positions: painter.drawImage(posX, y, img) posX += img.width() painter.end() return result
def plot(self, dataToPlot, times=None, save=False): if not dataToPlot.equals(self.data): self.minYLeft, self.maxYLeft, self.minYRight, self.maxYRight = None, None, None, None self.data = dataToPlot self.data.to_clipboard() self.plotItem.clear() try: self.plotItem.scene().removeItem(self.plot2) except AttributeError: pass x1 = self.data.iloc[:, 0] y1 = self.data.iloc[:, 1] y2 = self.data.iloc[:, 2] x2 = self.data.iloc[:, 3] y3 = self.data.iloc[:, 4] for g in (x1, y1, y2, x2, y3): g.dropna(inplace=True) x1 = [i.to_pydatetime().timestamp() for i in x1.to_list()] x2 = [i.to_pydatetime().timestamp() for i in x2.to_list()] self.plotItem.addLegend().clear() self.plotItem.plot(x1, y1, pen=pg.mkPen('g', width=3), name='Pressure') self.plotItem.plot(x1, y2, pen=pg.mkPen('r', width=3), name="Temperature") self.plot2.clear() self.plotItem.scene().addItem(self.plot2) self.plotItem.getAxis('right').linkToView(self.plot2) self.plot2.setXLink(self.plotItem) self.updateViews() self.plotItem.vb.sigResized.connect(self.updateViews) curve3 = pg.PlotDataItem(x2, y3, name='Depth', pen=pg.mkPen('b', width=3)) self.plot2.addItem(curve3) self.plotItem.addLegend().addItem(curve3, 'Depth') self.plotItem.getViewBox().autoRange() range = self.plotItem.getViewBox().viewRange()[0] minXFirstLeft, maxXFirstLeft = range[0], range[1] self.plot2.autoRange() range = self.plot2.viewRange()[0] minXFirstRight, maxXFirstRight = range[0], range[1] self.plot2.setXRange(min(minXFirstRight, minXFirstLeft), max(maxXFirstRight, maxXFirstLeft)) if (self.minYLeft, self.maxYLeft, self.minYRight, self.maxYRight) == (None, None, None, None): range = self.plotItem.getViewBox().viewRange()[1] self.minYLeft, self.maxYLeft = range[0], range[1] range = self.plot2.viewRange()[1] self.minYRight, self.maxYRight = range[0], range[1] if save: exporter = ImageExporter(self.plotItem) exporter.parameters()['width'] = 580 exporter.parameters()['height'] = 450 buffer = QBuffer() buffer.open(QIODevice.ReadWrite) exporter.export(toBytes=True).save(buffer, "PNG") buffer.seek(0) fig = BytesIO(buffer.readAll()) return fig else: if times is not None: self.button1.setVisible(True) self.button2.setVisible(True) vLines1, vLines2 = [self.makeInfLine(time, 0) for time in times[0]], \ [self.makeInfLine(time, 1) for time in times[1]] for line in chain(vLines1, vLines2): self.plotItem.addItem(line) line.infLineSignal.connect(self.emittingToMain)
def test_ImageExporter_filename_dialog(): """Tests ImageExporter code path that opens a file dialog. Regression test for pull request 1133.""" p = pg.plot() exp = ImageExporter(p.getPlotItem()) exp.export()
def saveFig(): dirName = "/mnt/odrive/HPD/Cooldown150605/" fname = "test.png" dataPath = dirName + fname exporter = IE.ImageExporter(plt) exporter.export(dataPath)
class MultiRoiViewBox(pg.ViewBox): sigROIchanged = QtCore.Signal(object) def __init__(self,parent=None,border=None,lockAspect=False,enableMouse=True,invertY=False,enableMenu=True,name=None): pg.ViewBox.__init__(self,parent,border,lockAspect,enableMouse,invertY,enableMenu,name) self.rois = [] self.currentROIindex = None self.img = None self.menu = None self.menu = self.getMenu(None) self.drawROImode = False self.drawingROI = None def getContextMenus(self,ev): return None def raiseContextMenu(self, ev): if not self.menuEnabled(): return menu = self.getMenu(ev) pos = ev.screenPos() menu.popup(QtCore.QPoint(pos.x(), pos.y())) def export(self): self.exp = ImageExporter(self) self.exp.export() def mouseClickEvent(self, ev): if self.drawROImode: ev.accept() self.drawPolygonRoi(ev) elif ev.button() == QtCore.Qt.RightButton and self.menuEnabled(): ev.accept() self.raiseContextMenu(ev) def addPolyRoiRequest(self): """Function to add a Polygon ROI""" self.drawROImode = True for roi in self.rois: roi.setActive(False) def endPolyRoiRequest(self): self.drawROImode = False # Deactivate drawing mode self.drawingROI = None # No roi being drawn, so set to None for r in self.rois: r.setActive(True) def addPolyLineROI(self,handlePositions): roi = PolyLineROIcustom(handlePositions=handlePositions,removable=True) roi.setName('ROI-%i'% self.getROIid()) self.addItem(roi) # Add roi to viewbox self.rois.append(roi) # Add to list of rois self.selectROI(roi) self.sortROIs() self.setCurrentROIindex(roi) roi.translatable = True roi.setActive(True) for seg in roi.segments: seg.setSelectable(True) for h in roi.handles: h['item'].setSelectable(True) # Setup signals roi.sigClicked.connect(self.selectROI) roi.sigRegionChanged.connect(self.roiChanged) roi.sigRemoveRequested.connect(self.removeROI) roi.sigCopyRequested.connect(self.copyROI) roi.sigSaveRequested.connect(self.saveROI) def drawPolygonRoi(self,ev): "Function to draw a polygon ROI" roi = self.drawingROI pos = self.mapSceneToView(ev.scenePos()) if ev.button() == QtCore.Qt.LeftButton: if roi is None: roi = PolyLineROIcustom(removable = False) roi.setName('ROI-%i'% self.getROIid()) # Do this before self.selectROIs(roi) self.drawingROI = roi self.addItem(roi) # Add roi to viewbox self.rois.append(roi) # Add to list of rois self.selectROI(roi) self.sortROIs() self.setCurrentROIindex(roi) roi.translatable = False roi.addFreeHandle(pos) roi.addFreeHandle(pos) h = roi.handles[-1]['item'] h.scene().sigMouseMoved.connect(h.movePoint) else: h = roi.handles[-1]['item'] h.scene().sigMouseMoved.disconnect() roi.addFreeHandle(pos) h = roi.handles[-1]['item'] h.scene().sigMouseMoved.connect(h.movePoint) # Add a segment between the handles roi.addSegment(roi.handles[-2]['item'],roi.handles[-1]['item']) # Set segment and handles to non-selectable seg = roi.segments[-1] seg.setSelectable(False) for h in seg.handles: h['item'].setSelectable(False) elif (ev.button() == QtCore.Qt.MiddleButton) or \ (ev.button() == QtCore.Qt.RightButton and (roi==None or len(roi.segments)<3)): if roi!=None: # Remove handle and disconnect from scene h = roi.handles[-1]['item'] h.scene().sigMouseMoved.disconnect() roi.removeHandle(h) # Removed roi from viewbox self.removeItem(roi) self.rois.pop(self.currentROIindex) self.setCurrentROIindex(None) # Exit ROI drawing mode self.endPolyRoiRequest() elif ev.button() == QtCore.Qt.RightButton: # Remove last handle h = roi.handles[-1]['item'] h.scene().sigMouseMoved.disconnect() roi.removeHandle(h) # Add segment to close ROI roi.addSegment(roi.handles[-1]['item'],roi.handles[0]['item']) # Setup signals roi.sigClicked.connect(self.selectROI) roi.sigRegionChanged.connect(self.roiChanged) roi.sigRemoveRequested.connect(self.removeROI) roi.sigCopyRequested.connect(self.copyROI) roi.sigSaveRequested.connect(self.saveROI) # Re-activate mouse clicks for all roi, segments and handles roi.removable = True roi.translatable = True for seg in roi.segments: seg.setSelectable(True) for h in roi.handles: h['item'].setSelectable(True) # Exit ROI drawing mode self.endPolyRoiRequest() def getMenu(self,event): if self.menu is None: self.menu = QtGui.QMenu() # Submenu to add ROIs self.submenu = QtGui.QMenu("Add ROI",self.menu) self.addROIRectAct = QtGui.QAction("Rectangular", self.submenu) self.addROIPolyAct = QtGui.QAction("Polygon", self.submenu) self.addROIRectAct.triggered.connect(self.addROI) self.addROIPolyAct.triggered.connect(self.addPolyRoiRequest) self.submenu.addAction(self.addROIRectAct) self.submenu.addAction(self.addROIPolyAct) self.loadImageAct = QtGui.QAction("Load image", self.menu) self.loadImageAct.triggered.connect(self.loadImage) self.loadROIAct = QtGui.QAction("Load ROI", self.menu) self.viewAll = QtGui.QAction("View All", self.menu) self.viewAll.triggered[()].connect(self.autoRange) self.menu.addAction(self.loadImageAct) self.menu.addAction(self.viewAll) self.menu.addSeparator() self.menu.addMenu(self.submenu) self.menu.addAction(self.loadROIAct) # Update action event. This enables passing of the event to the fuction connected to the # action i.e. event will be passed to self.addRoiRequest when a Rectangular ROI is clicked #self.addROIRectAct.updateEvent(event) #self.addROIPolyAct.updateEvent(event) return self.menu def setCurrentROIindex(self,roi=None): """ Use this function to change currentROIindex value to ensure a signal is emitted""" if roi==None: self.currentROIindex = None else: self.currentROIindex = self.rois.index(roi) self.sigROIchanged.emit(roi) def roiChanged(self,roi): self.sigROIchanged.emit(roi) def getCurrentROIindex(self): return self.currentROIindex def selectROI(self,roi): """ Selection control of ROIs """ # If no ROI is currently selected (currentROIindex is None), select roi if self.currentROIindex==None: roi.setSelected(True) self.setCurrentROIindex(roi) # If an ROI is already selected... else: roiSelected = self.rois[self.currentROIindex] roiSelected.setSelected(False) # If a different roi is already selected, then select roi if self.currentROIindex != self.rois.index(roi): self.setCurrentROIindex(roi) roi.setSelected(True) # If roi is already selected, then unselect else: self.setCurrentROIindex(None) def addRoiRequest(self,ev): """ Function to addROI at an event screen position """ # Get position pos = self.mapSceneToView(ev.scenePos()) xpos = pos.x() ypos = pos.y() # Shift down by size xr,yr = self.viewRange() xsize = 0.25*(xr[1]-xr[0]) ysize = 0.25*(yr[1]-yr[0]) xysize = min(xsize,ysize) if xysize==0: xysize=100 ypos -= xysize # Create ROI xypos = (xpos,ypos) self.addROI(pos=xypos) def addROI(self,pos=None,size=None,angle=0.0): """ Add an ROI to the ViewBox """ xr,yr = self.viewRange() if pos is None: posx = xr[0]+0.05*(xr[1]-xr[0]) posy = yr[0]+0.05*(yr[1]-yr[0]) pos = [posx,posy] if size is None: xsize = 0.25*(xr[1]-xr[0]) ysize = 0.25*(yr[1]-yr[0]) xysize = min(xsize,ysize) if xysize==0: xysize=100 size = [xysize,xysize] roi = RectROIcustom(pos,size,angle,removable=True,pen=(255,0,0)) # Setup signals roi.setName('ROI-%i'% self.getROIid()) roi.sigClicked.connect(self.selectROI) roi.sigRegionChanged.connect(self.roiChanged) roi.sigRemoveRequested.connect(self.removeROI) roi.sigCopyRequested.connect(self.copyROI) roi.sigSaveRequested.connect(self.saveROI) # Keep track of rois self.addItem(roi) self.rois.append(roi) self.selectROI(roi) self.sortROIs() self.setCurrentROIindex(roi) def sortROIs(self): """ Sort self.rois by roi name and adjust self.currentROIindex as necessary """ if len(self.rois)==0: return if self.currentROIindex==None: self.rois.sort() else: roiCurrent = self.rois[self.currentROIindex] self.rois.sort() self.currentROIindex = self.rois.index(roiCurrent) def getROIid(self): """ Get available and unique number for ROI name """ nums = [ int(roi.name.split('-')[-1]) for roi in self.rois if roi.name!=None ] nid = 1 if len(nums)>0: while(True): if nid not in nums: break nid+=1 return nid def copyROI(self,offset=0.0): """ Copy current ROI. Offset from original for visibility """ if self.currentROIindex!=None: osFract = 0.05 roi = self.rois[self.currentROIindex] # For rectangular ROI, offset by a fraction of the rotated size if type(roi)==RectROIcustom: roiState = roi.getState() pos = roiState['pos'] size = roiState['size'] angle = roiState['angle'] dx,dy = np.array(size)*osFract ang = np.radians(angle) cosa = np.cos(ang) sina = np.sin(ang) dxt = dx*cosa - dy*sina dyt = dx*sina + dy*cosa offset = QtCore.QPointF(dxt,dyt) self.addROI(pos+offset,size,angle) # For a polyline ROI, offset by a fraction of the bounding rectangle if type(roi)==PolyLineROIcustom: br = roi.shape().boundingRect() size = np.array([br.width(),br.height()]) osx,osy = size * osFract offset = QtCore.QPointF(osx,osy) hps = [i[-1] for i in roi.getSceneHandlePositions(index=None)] hpsOffset = [self.mapSceneToView(hp)+offset for hp in hps] self.addPolyLineROI(hpsOffset) def saveROI(self): """ Save the highlighted ROI to file """ if self.currentROIindex!=None: roi = self.rois[self.currentROIindex] fileName = QtGui.QFileDialog.getSaveFileName(None,self.tr("Save ROI"),QtCore.QDir.currentPath(),self.tr("ROI (*.roi)")) # Fix for PyQt/PySide compatibility. PyQt returns a QString, whereas PySide returns a tuple (first entry is filename as string) if isinstance(fileName,types.TupleType): fileName = fileName[0] if hasattr(QtCore,'QString') and isinstance(fileName, QtCore.QString): fileName = str(fileName) if not fileName=='': if type(roi)==RectROIcustom: roiState = roi.saveState() roiState['type']='RectROIcustom' elif type(roi)==PolyLineROIcustom: roiState = {} hps = [self.mapSceneToView(i[-1]) for i in roi.getSceneHandlePositions(index=None)] hps = [[hp.x(),hp.y()] for hp in hps] roiState['type']='PolyLineROIcustom' roiState['handlePositions'] = hps pickle.dump( roiState, open( fileName, "wb" ) ) def loadROI(self): """ Load a previously saved ROI from file """ fileNames = QtGui.QFileDialog.getOpenFileNames(None,self.tr("Load ROI"),QtCore.QDir.currentPath(),self.tr("ROI (*.roi)")) # Fix for PyQt/PySide compatibility. PyQt returns a QString, whereas PySide returns a tuple (first entry is filename as string) if isinstance(fileNames,types.TupleType): fileNames = fileNames[0] if hasattr(QtCore,'QStringList') and isinstance(fileNames, QtCore.QStringList): fileNames = [str(i) for i in fileNames] if len(fileNames)>0: for fileName in fileNames: if fileName!='': roiState = pickle.load( open(fileName, "rb") ) if roiState['type']=='RectROIcustom': self.addROI(roiState['pos'],roiState['size'],roiState['angle']) elif roiState['type']=='PolyLineROIcustom': self.addPolyLineROI(roiState['handlePositions']) def removeROI(self): """ Delete the highlighted ROI """ if self.currentROIindex!=None: roi = self.rois[self.currentROIindex] self.rois.pop(self.currentROIindex) self.removeItem(roi) self.setCurrentROIindex(None) def loadImage(self): fileName = QtGui.QFileDialog.getOpenFileName(None, self.tr("Load image"), QtCore.QDir.currentPath()) if fileName!='': try: imgarr = np.array(Image.open(str(fileName))) imgarr = imgarr.swapaxes(0,1) if imgarr.ndim==2: imgarr = imgarr[:,::-1] elif imgarr.ndim==3: imgarr = imgarr[:,::-1,:] self.imgarr = imgarr except: pass else: self.enableAutoRange() self.showImage(self.imgarr) self.disableAutoRange() def showImage(self,arr): if arr is None: self.img = None return if self.img==None: self.img = pg.ImageItem(arr,autoRange=False,autoLevels=False) self.addItem(self.img) self.img.setImage(arr,autoLevels=False)
def export(self): self.exp = ImageExporter(self) self.exp.export()
def save(self): self.timer.stop() self.deque = deque() firstName = self.plots.lineName.text() firstName = firstName[0].upper() + firstName[1:] lastName = self.plots.lineSurname.text().split(' ') lastName[-1] = lastName[-1][0].upper() + lastName[-1][1:] lastName = ' '.join(lastName) name = '{} {}'.format(firstName, lastName) self.globalScores[name] = [ int(self.plots.lineAge.text()), self.maxPower, self.maxFrequency ] self.localScores[name] = [ int(self.plots.lineAge.text()), self.maxPower, self.maxFrequency ] # update highscores self.dumpScores() # update scores window self.updateScoresSignal.emit() pen = pg.mkPen(color=(0, 0, 0), width=2) pg.setConfigOption('background', 'w') timePlot = pg.PlotWidget() timePlot.setRange(yRange=[1.2 * -2**15, 1.2 * 2**15]) timePlot.setBackground(None) timePlot.hideAxis('left') timePlot.hideAxis('bottom') timePlot.resize(800, 200) timeCurve = timePlot.plot(self.timeAxis, self.audioData[::self.DECIMATION], pen=pen) # create rotated version of spectrum # labelStyle = {'color': '#000', 'font-size': '16px'} # spectrumPlot = pg.PlotWidget() # # spectrumPlot.setTitle(title='Power Spectral Density', **labelStyle) # # spectrumPlot.setLabel('bottom', 'frequency (Hz)', **labelStyle) # # spectrumPlot.setLabel('left', 'power spectral density (dB)', **labelStyle) # spectrumPlot.getAxis("left").setWidth(200) # spectrumPlot.getAxis('left').setPen(pen) # spectrumPlot.getAxis('bottom').setPen(pen) # #spectrumPlot.setBackground(None) # spectrumPlot.getPlotItem().setLogMode(True, False) # spectrumPlot.getPlotItem().setRange( # xRange=[1, np.log10(self.SAMPLE_RATE // 2)], # yRange=[0, self.SPECTRUM_MAX]) # spectrumPlot.getAxis('left').setTicks( # [[(x, str(x)) for x in range(self.SPECTRUM_MIN, self.SPECTRUM_MAX, 20)]]) # spectrumPlot.getAxis('bottom').setTicks( # [[(x, str(int(10**x))) for x in [1, 2, 3, 4, 5]]]) # spectrumCurve = spectrumPlot.plot(self.spectrumScale, self.maxSpectrum, pen=pen) # export plots to png # exporter = ImageExporter(spectrumPlot.plotItem) # exporter.parameters()['width'] = 2000 # exporter.export('images/spectrum.png') exporter = ImageExporter(timePlot.plotItem) exporter.parameters()['width'] = 2000 exporter.export('images/timeseries.png') exporter = ImageExporter(self.spectrogramImage) exporter.parameters()['width'] = 2000 exporter.export('images/spectrogram.png') diplomaPath = createDiploma(firstName, lastName, self.maxPower, self.maxFrequency) time.sleep(0.5)
def save_plot_to_clipboard_as_png(self, plot_item): self.img_exporter = ImageExporter(plot_item) self.img_exporter.export(copy=True)