def createBarChartA(self, dataDict, title, type): f1 = plt.figure(figsize=(1.5625, 1.5)) #f1.set_facecolor(None) #f1.patch.set_alpha(0.0) temp = f1.add_subplot(111) my_colors = list( islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(dataDict))) temp.bar(range(len(dataDict)), dataDict.values(), align='center', width=0.2, color=my_colors) temp.set_xticks(range(len(dataDict))) temp.set_xticklabels(dataDict.keys()) plt.setp(temp.get_xticklabels(), rotation=20, horizontalalignment='right') canvas2 = FigureCanvas(f1) plt.gcf().subplots_adjust(bottom=0.5) plt.title(title) canvas2.setMinimumWidth(150) canvas2.setMinimumHeight(150) self.statsFigures[type] = f1 return canvas2
def one_dim_integrate(self): """ This creates the bottom left tile and also creates an instance of the IntegrationPlot class for handling the plotting of the image Parameters ---------- self Returns ------- None """ figure = plt.figure() canvas = FigureCanvas(figure) FigureCanvas.setSizePolicy(canvas, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) FigureCanvas.updateGeometry(canvas) canvas.setMinimumHeight(200) self.one_dim_plot = IntegrationPlot(self.int_data_dict, self.key_list, figure, canvas) toolbar = NavigationToolBar(canvas, self) layout = QtGui.QVBoxLayout() layout.addWidget(toolbar) layout.addWidget(canvas) self.display_box_2.addStretch() self.display_box_2.addLayout(layout)
def createBarChartCorrelation(self, dataTupple): f1 = plt.figure(figsize=(1.5625, 1.5)) #f1.set_facecolor(None) #f1.patch.set_alpha(0.0) temp = f1.add_subplot(111) x_axis_Titles = [function[0] for function in dataTupple] dataPoints = [function[1] for function in dataTupple] my_colors = list( islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(dataTupple))) temp.bar(range(len(dataTupple)), dataPoints, align='center', width=0.2, color=my_colors) temp.set_xticks(range(len(dataTupple))) temp.set_xticklabels(x_axis_Titles) plt.setp(temp.get_xticklabels(), rotation=20, horizontalalignment='right') canvas2 = FigureCanvas(f1) plt.gcf().subplots_adjust(bottom=0.5) plt.gca().set_ylim([min(dataPoints) - 0.2, 1]) plt.title("Function Correlation") canvas2.setMinimumWidth(150) canvas2.setMinimumHeight(150) self.statsFigures["FunctionCorrelations"] = f1 return canvas2
class View(QWidget): def __init__(self, parent = None): super(View, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.canvas.setMinimumHeight(200) toolbar = NavigationToolbar(self.canvas, self) self.navigation = Navigation.Navigation(self) self.navigation.activeItemChanged.connect(self.updateVisualisation) self.navigation.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum) self.info = Info.Info(self) hLayout = QHBoxLayout() hLayout.addWidget(self.navigation) hLayout.addWidget(self.info) layout = QVBoxLayout(self) layout.addLayout(hLayout) layout.addWidget(toolbar) layout.addWidget(self.canvas) def updateVisualisation(self): source = self.navigation.getActiveSource() self.info.update(source) numPlots = sum([1 if source.slipRates[i] is not None else 0 for i in range(3)]) self.figure.clear() for i in range(3): if source.slipRates[i] is not None: p = self.figure.add_subplot(numPlots, 1, i+1) p.set_xlabel('t [s]') p.set_ylabel('u{} [m/s]'.format(i+1)) time = [source.info[PointSource.Tinit] + j*source.info[PointSource.Dt] for j in range(len(source.slipRates[i]))] p.plot(time, source.slipRates[i]) if numPlots > 0: self.figure.tight_layout() self.canvas.draw()
def createBarChart(self): D = {u'Label0': 26, u'Label1': 17, u'Label2': 30} f1 = plt.figure(figsize=(1.5625, 0.2)) #f1.set_facecolor(None) #f1.patch.set_alpha(0.0) temp = f1.add_subplot(111) my_colors = list(islice(cycle(['b', 'r', 'g', 'y', 'k']), None, len(D))) temp.bar(range(len(D)), D.values(), align='center', width=0.2, color=my_colors) canvas2 = FigureCanvas(f1) canvas2.setMinimumWidth(150) canvas2.setMinimumHeight(150) return canvas2
def createPieChart(self): # The slices will be ordered and plotted counter-clockwise. labels = 'User', 'Compiler', 'Other' sizes = [15, 55, 30] colors = ['blue', '#FA8500', '#80390A'] explode = (0, 0.1, 0) # only "explode" the 2nd slice (i.e. 'Hogs') figure = plt.figure(figsize=(1.5625, 0.2)) #figure.set_facecolor(None) #figure.patch.set_alpha(0.0) canvas = FigureCanvas(figure) axes = figure.add_subplot(111) axes.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True, startangle=90) canvas.setMinimumWidth(150) canvas.setMinimumHeight(150) return canvas
def createBoxPlot(self, dataDict): # basic plot f1 = plt.figure(figsize=(1.5625, 0.2)) #f1.set_facecolor(None) #f1.patch.set_alpha(0.0) temp = f1.add_subplot(111) ## Create data np.random.seed(10) collectn_1 = dataDict.values() collectn_2 = np.random.normal(80, 30, 200) collectn_3 = np.random.normal(90, 20, 200) collectn_4 = np.random.normal(70, 25, 200) ## combine these different collections into a list data_to_plot = [collectn_1, collectn_2, collectn_3, collectn_4] # fake up some more data temp.boxplot(data_to_plot) # multiple box plots on one figure canvas2 = FigureCanvas(f1) canvas2.setMinimumWidth(150) canvas2.setMinimumHeight(150) return canvas2
class SignalViewerWidget(QtGui.QWidget): """Shows different visualizations of a seismic signal (magnitude, envelope, spectrogram, characteristic function). Allows the user to manipulate it (navigate through it, zoom in/out, edit detected events, select threshold value, etc...) """ CF_loaded = QtCore.Signal(bool) event_selected = QtCore.Signal(rc.ApasvoEvent) def __init__(self, parent, document=None): super(SignalViewerWidget, self).__init__(parent) self.document = document self.xmin = 0.0 self.xmax = 0.0 self.xleft = 0.0 self.xright = 0.0 self.time = np.array([]) self.fs = 0.0 self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.fig, _ = plt.subplots(3, 1) self.signal_ax = self.fig.axes[0] self.cf_ax = self.fig.axes[1] self.specgram_ax = self.fig.axes[2] self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy( QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.eventMarkers = {} self.last_right_clicked_event = None self.thresholdMarker = None self.playback_marker = None self.selector = SpanSelector(self.fig) self.minimap = MiniMap(self, self.signal_ax, None) # Load Spectrogram settings self.update_specgram_settings() # Animation related attributes self.background = None self.animated = False # Create context menus self.event_context_menu = QtGui.QMenu(self) self.takanami_on_event_action = QtGui.QAction( "Apply Takanami to Event", self) self.takanami_on_event_action.setStatusTip( "Refine event position by using Takanami algorithm") self.event_context_menu.addAction(self.takanami_on_event_action) self.takanami_on_event_action.triggered.connect( self.apply_takanami_to_selected_event) self.selection_context_menu = QtGui.QMenu(self) self.create_event_action = QtGui.QAction( "Create New Event on Selection", self) self.create_event_action.setStatusTip( "Create a new event on selection") self.takanami_on_selection_action = QtGui.QAction( "Apply Takanami to Selection", self) self.takanami_on_selection_action.setStatusTip( "Apply Takanami algorithm to selection") self.selection_context_menu.addAction(self.create_event_action) self.selection_context_menu.addAction( self.takanami_on_selection_action) self.create_event_action.triggered.connect( self.create_event_on_selection) self.takanami_on_selection_action.triggered.connect( self.apply_takanami_to_selection) # format axes formatter = FuncFormatter(lambda x, pos: clt.float_secs_2_string_date( x, self.document.record.starttime)) for ax in self.fig.axes: ax.callbacks.connect('xlim_changed', self.on_xlim_change) ax.xaxis.set_major_formatter(formatter) plt.setp(ax.get_xticklabels(), visible=True) ax.grid(True, which='both') self.specgram_ax.callbacks.connect('ylim_changed', self.on_ylim_change) self.specgram_ax.set_xlabel('Time (seconds)') plt.setp(self.signal_ax.get_yticklabels(), visible=False) #self.signal_ax.set_ylabel('Signal Amp.') self.cf_ax.set_ylabel('CF Amp.') self.specgram_ax.set_ylabel('Frequency (Hz)') # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) self.layout.addWidget(self.minimap) self.selector.toggled.connect(self.minimap.set_selection_visible) self.selector.valueChanged.connect(self.minimap.set_selection_limits) self.selector.right_clicked.connect(self.on_selector_right_clicked) if self.document is not None: self.set_record(document) @property def data_loaded(self): return self.document is not None def set_record(self, document, step=120.0): self.document = document self.fs = self.document.record.fs self.signal = self.document.record.signal self.envelope = env.envelope(self.signal) self.cf = self.document.record.cf self.time = np.linspace(0, len(self.signal) / self.fs, num=len(self.signal), endpoint=False) self.xmax = self.time[-1] # Draw minimap self.minimap.minimapSelector.set( visible=False) # Hide minimap selector while loading self.minimap.set_record(self.document.record, step) # Plot signal step_samples = step * self.fs self._signal_data = self.signal_ax.plot(self.time[:step_samples], self.signal[:step_samples], color='black', rasterized=True)[0] # Plot envelope self._envelope_data = self.signal_ax.plot(self.time[:step_samples], self.envelope[:step_samples], color='red', rasterized=True)[0] # Adjust y axis for signal plot signal_yaxis_max_value = max(np.max(self.signal), np.max(self.envelope)) signal_yaxis_min_value = np.min(self.signal) plotting.adjust_axes_height(self.signal_ax, max_value=signal_yaxis_max_value, min_value=signal_yaxis_min_value) # Plot CF cf_loaded = (self.cf.size != 0) self.set_cf_visible(cf_loaded) self.CF_loaded.emit(cf_loaded) cf_step_samples = min(step_samples, len(self.cf)) self._cf_data = self.cf_ax.plot(self.time[:cf_step_samples], self.cf[:cf_step_samples], color='black', rasterized=True)[0] # Adjust y axis for CF plot if cf_loaded: plotting.adjust_axes_height(self.cf_ax, max_value=np.max(self.cf), min_value=np.min(self.cf)) self.thresholdMarker = ThresholdMarker(self.cf_ax) # Plot espectrogram plotting.plot_specgram(self.specgram_ax, self.signal, self.fs, nfft=self.specgram_windowlen, noverlap=self.specgram_noverlap, window=self.specgram_window) # Set the span selector self.selector.fs = self.fs self.selector.set_active(False) self.selector.set_selection_limits(self.xmin, self.xmax) # Set the playback marker self.playback_marker = PlayBackMarker(self.fig, self) # Set the initial xlimits self.set_xlim(0, step) self.subplots_adjust() # Set event markers self.eventMarkers = {} for event in self.document.record.events: self.create_event(event) # Now activate selector again on minimap self.minimap.minimapSelector.set(visible=True) self.minimap.draw() def unset_record(self): self.document = None self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.xmin, self.xmax = 0.0, 0.0 self.eventMarkers = {} # Clear axes self.signal_ax.lines = [] self.cf_ax.lines = [] self.specgram_ax.lines = [] self.specgram_ax.images = [] self.CF_loaded.emit(False) def update_cf(self): if self.data_loaded: self.cf = self.document.record.cf self._cf_data.set_xdata(self.time[:len(self.cf)]) self._cf_data.set_ydata(self.cf) plotting.adjust_axes_height(self.cf_ax) cf_loaded = (self.cf.size != 0) self.CF_loaded.emit(cf_loaded) self.set_cf_visible(cf_loaded) self.draw() def create_events(self, new_events_set): for event in new_events_set.get(self.document.record.uuid, []): self.create_event(event) def create_event(self, event): event_id = event.resource_id.uuid if event_id not in self.eventMarkers: marker = EventMarker(self.fig, self.minimap, self.document, event) self.eventMarkers[event_id] = marker marker.event_selected.connect(self.event_selected.emit) marker.right_clicked.connect(self.on_event_right_clicked) def delete_events(self, new_events_set): for event in new_events_set.get(self.document.record.uuid, []): self.delete_event(event) def delete_event(self, event): event_id = event.resource_id.uuid self.eventMarkers[event_id].remove() self.eventMarkers.pop(event_id) def update_event(self, event): self.eventMarkers[event.resource_id.uuid].update() def set_xlim(self, l, r): xmin = max(0, l) xmax = min(self.xmax, r) self.signal_ax.set_xlim(xmin, xmax) def on_xlim_change(self, ax): xmin, xmax = ax.get_xlim() if (self.xleft, self.xright) != (xmin, xmax): self.xleft, self.xright = xmin, xmax if self.xmin <= xmin <= xmax <= self.xmax: # Update minimap selector if (xmin, xmax) != self.minimap.get_selector_limits(): self.minimap.set_selector_limits(xmin, xmax) # Update axes for axes in self.fig.axes: if ax != axes: axes.set_xlim(xmin, xmax) # Update data xmin = int(max(0, xmin) * self.fs) xmax = int(min(self.xmax, xmax) * self.fs) pixel_width = np.ceil(self.fig.get_figwidth() * self.fig.get_dpi()) if self._signal_data is not None: x_data, y_data = plotting.reduce_data( self.time, self.signal, pixel_width, xmin, xmax) self._signal_data.set_xdata(x_data) self._signal_data.set_ydata(y_data) if self._envelope_data is not None: x_data, y_data = plotting.reduce_data( self.time, self.envelope, pixel_width, xmin, xmax) self._envelope_data.set_xdata(x_data) self._envelope_data.set_ydata(y_data) if self._cf_data is not None and self.cf_ax.get_visible(): x_data, y_data = plotting.reduce_data( self.time[:len(self.cf)], self.cf, pixel_width, xmin, xmax) self._cf_data.set_xdata(x_data) self._cf_data.set_ydata(y_data) # Draw graph self.draw() else: xmin = max(self.xmin, xmin) xmax = min(self.xmax, xmax) ax.set_xlim(xmin, xmax) def on_ylim_change(self, ax): if self.data_loaded: if ax == self.specgram_ax: ymin, ymax = ax.get_ylim() nyquist_freq = (self.fs / 2.0) if ymin < 0.0: ax.set_ylim(0.0, ymax) elif ymax > nyquist_freq: ax.set_ylim(ymin, nyquist_freq) def set_event_selection(self, events): event_id_list = [event.resource_id.uuid for event in events] for event_id in self.eventMarkers: self.eventMarkers[event_id].set_selected(event_id in event_id_list) self.draw() self.minimap.draw() def set_position(self, pos): """""" xmin, xmax = self.signal_ax.get_xlim() mrange = xmax - xmin l, r = pos - mrange / 2.0, pos + mrange / 2.0 if l < self.xmin: l, r = self.xmin, mrange elif r > self.xmax: l, r = self.xmax - mrange, self.xmax self.set_xlim(l, r) def goto_event(self, event): if event.resource_id.uuid in self.eventMarkers: self.set_position(event.stime / self.fs) def showEvent(self, event): self.draw() self.minimap.draw_animate() def resizeEvent(self, event): self.draw() self.minimap.draw_animate() def set_signal_amplitude_visible(self, show_sa): if self._signal_data is not None and self._envelope_data is not None: if self._signal_data.get_visible() != show_sa: self._signal_data.set_visible(show_sa) show_axis = (self._signal_data.get_visible() + self._envelope_data.get_visible()) self.signal_ax.set_visible(show_axis) if self.data_loaded: self.subplots_adjust() self.draw() def set_signal_envelope_visible(self, show_se): if self._signal_data is not None and self._envelope_data is not None: if self._envelope_data.get_visible() != show_se: self._envelope_data.set_visible(show_se) show_axis = (self._signal_data.get_visible() + self._envelope_data.get_visible()) self.signal_ax.set_visible(show_axis) if self.data_loaded: self.subplots_adjust() self.draw() def set_cf_visible(self, show_cf): if self.cf_ax.get_visible() != show_cf: if self.data_loaded: if len(self.cf) <= 0: self.cf_ax.set_visible(False) else: self.cf_ax.set_visible(show_cf) self.subplots_adjust() self.draw() def set_espectrogram_visible(self, show_eg): if self.specgram_ax.get_visible() != show_eg: self.specgram_ax.set_visible(show_eg) if self.data_loaded: self.subplots_adjust() self.draw() def set_minimap_visible(self, show_mm): if self.minimap.get_visible() != show_mm: self.minimap.set_visible(show_mm) self.minimap.draw_animate() def set_threshold_visible(self, show_thr): if self.thresholdMarker: if self.thresholdMarker.get_visible() != show_thr: self.thresholdMarker.set_visible(show_thr) self.draw() def subplots_adjust(self): visible_subplots = [ ax for ax in self.fig.get_axes() if ax.get_visible() ] for i, ax in enumerate(visible_subplots): correct_geometry = (len(visible_subplots), 1, i + 1) if correct_geometry != ax.get_geometry(): ax.change_geometry(len(visible_subplots), 1, i + 1) # Adjust space between subplots self.fig.subplots_adjust(left=0.06, right=0.95, bottom=0.14, top=0.95, hspace=0.22) def get_selector_limits(self): return self.selector.get_selector_limits() def set_selector_limits(self, xleft, xright): self.selector.set_selector_limits(xleft, xright) def set_selection_enabled(self, value): self.selector.set_enabled(value) def set_playback_position(self, position): if self.playback_marker is not None: self.playback_marker.set_position(position) self.minimap.playback_marker.set_position(position) def set_playback_marker_visible(self, show_marker): if self.playback_marker is not None: self.playback_marker.set_visible(show_marker) self.minimap.playback_marker.set_visible(show_marker) def on_event_right_clicked(self, event): self.last_right_clicked_event = event self.event_context_menu.exec_(QtGui.QCursor.pos()) def apply_takanami_to_selected_event(self): takanamidialog.TakanamiDialog( self.document, seismic_event=self.last_right_clicked_event).exec_() def apply_takanami_to_selection(self): xleft, xright = self.get_selector_limits() takanamidialog.TakanamiDialog(self.document, xleft, xright).exec_() def create_event_on_selection(self): xleft, xright = self.get_selector_limits() xleft, xright = xleft * self.fs, xright * self.fs cf = self.cf[xleft:xright] if cf.size > 0: time = (xleft + np.argmax(cf)) else: time = (xleft + ((xright - xleft) / 2.0)) self.document.createEvent(time=time) def draw(self): if self.animated: self._draw_animate() else: self.canvas.draw_idle() def _draw_animate(self): self.canvas.restore_region(self.background) for artist in self._get_animated_artists(): if artist.get_visible(): ax = artist.get_axes() if ax is not None: if artist.get_axes().get_visible(): self.fig.draw_artist(artist) else: self.fig.draw_artist(artist) self.canvas.blit(self.fig.bbox) def _set_animated(self, value): if self.animated != value: self.animated = value for artist in self._get_animated_artists(): artist.set_animated(value) if self.animated == True: images = [] for ax in self.fig.axes: images.extend(ax.images) for image in images: image.set_visible(False) self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) for image in images: image.set_visible(True) def _get_animated_artists(self): artists = [] for ax in self.fig.axes: artists.extend(ax.images) artists.extend(ax.lines) artists.append(ax.xaxis) artists.append(ax.yaxis) artists.extend(ax.patches) artists.extend(ax.spines.values()) for artist in artists: yield artist def update_specgram_settings(self): # load specgram settings settings = QtCore.QSettings(_organization, _application_name) settings.beginGroup("specgram_settings") self.specgram_windowlen = int( settings.value('window_len', settingsdialog.SPECGRAM_WINDOW_LENGTHS[4])) self.specgram_noverlap = int( settings.value('noverlap', self.specgram_windowlen / 2)) self.specgram_window = settings.value('window', plotting.SPECGRAM_WINDOWS[2]) settings.endGroup() if self.data_loaded: # Plot espectrogram self.specgram_ax.images = [] # Save x-axis limits limits = self.signal_ax.get_xlim() # Draw spectrogram plotting.plot_specgram(self.specgram_ax, self.signal, self.fs, nfft=self.specgram_windowlen, noverlap=self.specgram_noverlap, window=self.specgram_window) # Restore x-axis limits self.signal_ax.set_xlim(*limits) def paintEvent(self, paintEvent): super(SignalViewerWidget, self).paintEvent(paintEvent) def on_selector_right_clicked(self): xleft, xright = self.get_selector_limits() self.takanami_on_selection_action.setEnabled( (xright - xleft) >= (takanamidialog.MINIMUM_MARGIN_IN_SECS * 2)) self.selection_context_menu.exec_(QtGui.QCursor.pos())
class MainWin(QMainWindow): #class AppForm(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowTitle('Main Window') #self.resize(1100,620) #self.move(200,200) # Initial window size/pos last saved self.settings = QSettings("greenbird") self.settings.beginGroup("MainWindow") self.resize(self.settings.value("size", QVariant(QSize(1100, 620))).toSize()); self.move(self.settings.value("pos", QVariant(QPoint(200, 200))).toPoint()) self.settings.endGroup() #screenShape = QDesktopWidget().screenGeometry() #self.resize( screenShape.width()*0.8,screenShape.width()*0.445 ) #self.setMinimumWidth(1100) #self.setMinimumHeight(610) #Tracer()() self.resizeEvent = self.on_resize # Retrieve initial data #self.data_init() #self.case_id_current = 0 self.create_menu() self.create_toolbar() self.create_main_frame() self.create_status_bar() self.on_draw() # Init plot #self.draw_fuelmap() #self.textbox.setText('1 2 3 4') #self.data_init() #self.case_cbox.setCurrentIndex(0) # Set default plot case #self.case_id_current = 0 #self.on_plot() # Init plot #self.on_draw() #self.draw_fuelmap() #Tracer()() def on_resize(self,event): self.axes.set_xlim(0,1.2) self.axes.set_ylim(0,1) def openFile(self): #file_choices = "inp (*.inp);;pickle (*.p)" file_choices = "Data files (*.inp *.p)" filename = unicode(QFileDialog.getOpenFileName(self, 'Open file', '', file_choices)) if filename: filext = os.path.splitext(filename)[1] if filext == ".p": self.load_pickle(filename) elif filext == ".inp": self.read_cax(filename) def load_pickle(self,filename): self.statusBar().showMessage('Importing data from %s' % filename, 2000) self.dataobj = casio() self.dataobj.loadpic(filename) self.init_pinobjects() #fuetype = 'SVEA-96' #self.dataobj.btf = btf(self.dataobj,fuetype) #self.setpincoords() #self.draw_fuelmap() #self.set_pinvalues() # Update case number list box ncases = len(self.dataobj.cases) for i in range(1,ncases+1): self.case_cbox.addItem(str(i)) self.connect(self.case_cbox, SIGNAL('currentIndexChanged(int)'), self.fig_update) self.fig_update() def dataobj_finished(self): print "dataobject constructed" self.init_pinobjects() # Perform reference quick calculation for base case print "Performing a reference quick calculation..." ncases = len(self.dataobj.cases) for case_num in range(ncases): self.quick_calc(case_num) #pyqt_trace() #self.thread.quit() #self.draw_fuelmap() #self.set_pinvalues() self.timer.stop() # Update case number list box #ncases = len(self.dataobj.cases) for i in range(1,ncases+1): self.case_cbox.addItem(str(i)) self.connect(self.case_cbox, SIGNAL('currentIndexChanged(int)'), self.fig_update) self.fig_update() self.progressbar.update(100) self.progressbar.setWindowTitle('All data imported') self.progressbar.button.setText('Ok') self.progressbar.button.clicked.disconnect(self.killThread) self.progressbar.button.clicked.connect(self.progressbar.close) self.progressbar.button.setEnabled(True) #pyqt_trace() #QMessageBox.information(self,"Done!","All data imported!") def progressbar_update(self,val=None): if val is not None: self.progressbar._value = max(val,self.progressbar._value) self.progressbar.update(self.progressbar._value) self.progressbar._value += 1 def killThread(self): print 'killThread' self.disconnect(self.timer,SIGNAL('timeout()'),self.progressbar_update) self.disconnect(self.thread,SIGNAL('finished()'),self.dataobj_finished) self.disconnect(self.thread,SIGNAL('progressbar_update(int)'),self.progressbar_update) self.thread._kill = True self.progressbar.close() #self.progressbar.close # self.thread.wait() # print 'killed' def read_cax(self,filename): msg = """ Click Yes to start importing data from cax files. This may take a while. Continue? """ msgBox = QMessageBox() ret = msgBox.information(self,"Importing data",msg.strip(),QMessageBox.Yes|QMessageBox.Cancel) #ret = msgBox.question(self,"Importing data",msg.strip(),QMessageBox.Yes|QMessageBox.Cancel) self.statusBar().showMessage('Importing data from %s' % filename, 2000) self._filename = filename if ret == QMessageBox.Yes: #self.progressbar = ProgressBar() #self.dataobj = casio() self.thread = dataThread(self) self.connect(self.thread,SIGNAL('finished()'),self.dataobj_finished) self.connect(self.thread,SIGNAL('progressbar_update(int)'),self.progressbar_update) self.thread.start() self.progressbar = ProgressBar() xpos = self.pos().x() + self.width()/2 - self.progressbar.width()/2 ypos = self.pos().y() + self.height()/2 - self.progressbar.height()/2 self.progressbar.move(xpos,ypos) self.progressbar.show() self.progressbar.button.setEnabled(False) self.progressbar.button.clicked.connect(self.killThread) #self.progressbar.button.clicked.connect(self.progressbar.close) self.timer = QTimer() self.connect(self.timer,SIGNAL('timeout()'),self.progressbar_update) self.progressbar._value = 1 self.timer.start(500) #time.sleep(20) #self.thread.terminate() #pyqt_trace() #print self.dataobj.data.caxfiles #self.dataobj = casio() #self.dataobj.readinp(filename) #self.dataobj.readcax() #self.dataobj.calcbtf() #fuetype = 'SVEA-96' #self.dataobj.btf = btf(self.dataobj,fuetype) #self.setpincoords() #self.draw_fuelmap() #self.set_pinvalues() #self.dataobj.savecas() else: return def saveData(self): file_choices = "Data files (*.p)" filename = unicode(QFileDialog.getSaveFileName(self, 'Open file', '', file_choices)) self.dataobj.savepic(filename) def plotWin(self): #print "Open plot window" if hasattr(self,'dataobj'): plotwin = PlotWin(self) plotwin.show() else: msg = "There is no data to plot." msgBox = QMessageBox() msgBox.information(self,"No data",msg.strip(),QMessageBox.Close) def init_pinobjects(self): self.pinobjects = [] ncases = len(self.dataobj.cases) for case_num in range(ncases): LFU = self.dataobj.cases[case_num].data.LFU ENR = self.dataobj.cases[case_num].data.ENR BA = self.dataobj.cases[case_num].data.BA pinlist = [] for i in range(LFU.shape[0]): for j in range(LFU.shape[1]): if LFU[i,j] > 0: pinobj = cpin(self.axes) pinobj.pos = [i,j] pinobj.ENR = ENR[i,j] pinobj.BA = BA[i,j] pinobj.LFU = LFU[i,j] pinlist.append(pinobj) self.pinobjects.append(pinlist) def set_pinvalues(self): #print "Set values" param_str = str(self.param_cbox.currentText()) case_num = int(self.case_cbox.currentIndex()) point_num = int(self.point_sbox.value()) #print param_str,case_num,point_num #self.table.setHorizontalHeaderItem(1,QTableWidgetItem(param_str)) #if param_str == 'FINT': param_str = 'POW' #if hasattr(self,'dataobj'): # data is loaded # if param_str == 'ENR': # pinvalues = getattr(self.dataobj.cases[case_num].data,param_str) # else: # pinvalues = getattr(self.dataobj.cases[case_num].statepts[point_num],param_str) # #print pinvalues ENR = getattr(self.dataobj.cases[case_num].data,'ENR') EXP = getattr(self.dataobj.cases[case_num].statepts[point_num],'EXP') FINT = getattr(self.dataobj.cases[case_num].statepts[point_num],'POW') #BTF = self.dataobj.btf.DOX[point_num,:,:] burnup = self.dataobj.cases[case_num].statepts[point_num].burnup try: btf_num = next(i for i,x in enumerate(self.dataobj.btf.burnpoints) if x == burnup) BTF = self.dataobj.btf.DOX[btf_num,:,:] except: BTF = np.zeros(np.shape(self.dataobj.btf.DOX)[1:]) BTF.fill(np.nan) npst = self.dataobj.cases[case_num].data.npst LFU = self.dataobj.cases[case_num].data.LFU BA = self.dataobj.cases[case_num].data.BA self.table.sortItems(0,Qt.AscendingOrder) # Sorting column 0 in ascending order self.setpincoords() #pyqt_trace() #row = 0 k = 0 for i in range(npst): for j in range(npst): if LFU[i,j] > 0: #if j != 5 and i !=5: # if not ((i==4 and j==4) or (i==4 and j==6) or (i==6 and j==4) or (i==6 and j==6)): #print i,j #print self.circlelist[k].text.get_text() self.pinobjects[case_num][k].EXP = EXP[i,j] self.pinobjects[case_num][k].FINT = FINT[i,j] self.pinobjects[case_num][k].BTF = BTF[i,j] #self.circlelist[k].ENR = ENR[i,j] #self.circlelist[k].EXP = EXP[i,j] #self.circlelist[k].FINT = FINT[i,j] #self.circlelist[k].BA = BA[i,j] #self.circlelist[k].BTF = BTF[i,j] #k += 1 #expval = QTableWidgetItem().setData(Qt.DisplayRole,EXP[i,j]) #self.table.setItem(row,1,expval) expItem = QTableWidgetItem() expItem.setData(Qt.EditRole, QVariant(float(np.round(EXP[i,j],3)))) fintItem = QTableWidgetItem() fintItem.setData(Qt.EditRole, QVariant(float(np.round(FINT[i,j],3)))) btfItem = QTableWidgetItem() btfItem.setData(Qt.EditRole, QVariant(float(np.round(BTF[i,j],3)))) self.table.setItem(k,1,expItem) self.table.setItem(k,2,fintItem) self.table.setItem(k,3,btfItem) k += 1 #self.table.setItem(row,1,expItem) #self.table.setItem(row,2,fintItem) #self.table.setItem(row,3,btfItem) #item.setData(Qt.EditRole, QVariant(float(FINT[i,j]))) #self.table.setItem(row,2,item) #self.table.setItem(row,1,QTableWidgetItem(str(EXP[i,j]))) #self.table.setItem(row,2,QTableWidgetItem(str(FINT[i,j]))) #self.table.setItem(row,3,QTableWidgetItem(str(0))) #if j != 5 and i !=5: # Ignore water cross #if not (np.all(LFU[i,:]==0) or np.all(LFU[:,j]==0)): # Ignore water cross # row += 1 burnup = self.dataobj.cases[case_num].statepts[point_num].burnup voi = self.dataobj.cases[case_num].statepts[point_num].voi vhi = self.dataobj.cases[case_num].statepts[point_num].vhi kinf = self.dataobj.cases[case_num].statepts[point_num].kinf fint = self.dataobj.cases[case_num].statepts[point_num].fint btf = BTF.max() tfu = self.dataobj.cases[case_num].statepts[point_num].tfu tmo = self.dataobj.cases[case_num].statepts[point_num].tmo self.statusBar().showMessage("Burnup=%.3f : VOI=%.0f : VHI=%.0f : Kinf=%.5f : Fint=%.3f : BTF=%.4f : TFU=%.0f : TMO=%.0f" % (burnup,voi,vhi,kinf,fint,btf,tfu,tmo)) #if param_str == 'ENR': # Print pin ENR npins = len(self.pinobjects[case_num]) #npins = len(self.circlelist) for i in range(npins): if self.pinobjects[case_num][i].BA == 0: j = next(j for j,cobj in enumerate(self.enrpinlist) if cobj.ENR == self.pinobjects[case_num][i].ENR) else: j = next(j for j,cobj in enumerate(self.enrpinlist) if cobj.BA == self.pinobjects[case_num][i].BA and cobj.ENR == self.pinobjects[case_num][i].ENR) self.pinobjects[case_num][i].LFU = j+1 fc = self.enrpinlist[j].circle.get_facecolor() if param_str == 'ENR': #if self.pinobjects[case_num][i].BA == 0: # j = next(j for j,cobj in enumerate(self.enrpinlist) if cobj.ENR == self.pinobjects[case_num][i].ENR) #else: # j = next(j for j,cobj in enumerate(self.enrpinlist) # if cobj.BA == self.pinobjects[case_num][i].BA and cobj.ENR == self.pinobjects[case_num][i].ENR) #if self.circlelist[i].BA == 0: # j = next(j for j,cobj in enumerate(self.enrpinlist) if cobj.ENR == self.circlelist[i].ENR) #else: # j = next(j for j,cobj in enumerate(self.enrpinlist) # if cobj.BA == self.circlelist[i].BA and cobj.ENR == self.circlelist[i].ENR) #fc = self.enrpinlist[j].circle.get_facecolor() text = self.enrpinlist[j].text.get_text() self.pinobjects[case_num][i].text.remove() self.pinobjects[case_num][i].set_text(text) #self.circlelist[i].set_text(text) #self.circlelist[i].circle.set_facecolor(fc) self.pinobjects[case_num][i].circle.set_facecolor(fc) elif param_str == 'BTF': #text = ('%.2f' % (self.pinobjects[case_num][i].BTF)) btf_ratio = self.pinobjects[case_num][i].BTF/btf*100 text = ('%.0f' % (btf_ratio)) self.pinobjects[case_num][i].text.remove() self.pinobjects[case_num][i].set_text(text) self.pinobjects[case_num][i].circle.set_facecolor(fc) elif param_str == 'EXP': if self.pinobjects[case_num][i].EXP < 10: text = ('%.1f' % (self.pinobjects[case_num][i].EXP)) else: text = ('%.0f' % (self.pinobjects[case_num][i].EXP)) self.pinobjects[case_num][i].text.remove() self.pinobjects[case_num][i].set_text(text) self.pinobjects[case_num][i].circle.set_facecolor(fc) #elif param_str == 'EXP': # if self.circlelist[i].EXP < 10: # text = ('%.1f' % (self.circlelist[i].EXP)) # else: # text = ('%.0f' % (self.circlelist[i].EXP)) # self.circlelist[i].set_text(text) elif param_str == 'FINT': if self.pinobjects[case_num][i].FINT < 10: text = ('%.1f' % (self.pinobjects[case_num][i].FINT)) else: text = ('%.0f' % (self.pinobjects[case_num][i].FINT)) self.pinobjects[case_num][i].text.remove() self.pinobjects[case_num][i].set_text(text) self.pinobjects[case_num][i].circle.set_facecolor(fc) #elif param_str == 'FINT': # if self.circlelist[i].FINT < 10: # text = ('%.1f' % (self.circlelist[i].FINT)) # else: # text = ('%.0f' % (self.circlelist[i].FINT)) # self.circlelist[i].set_text(text) self.canvas.draw() #self.circlelist[0].set_text(pinvalues[0,0]) def setpincoords(self): self.table.clearContents() #self.xlist = ('01','02','03','04','05','06','07','08','09','10') #self.ylist = ('A','B','C','D','E','F','G','H','I','J') case_num = int(self.case_cbox.currentIndex()) npin = len(self.pinobjects[case_num]) #npin = len(self.circlelist) self.table.setRowCount(npin) for i,pinobj in enumerate(self.pinobjects[case_num]): #for i,pinobj in enumerate(self.circlelist): coord_item = QTableWidgetItem(pinobj.coord) self.table.setVerticalHeaderItem(i,coord_item) i_item = QTableWidgetItem() i_item.setData(Qt.EditRole, QVariant(int(i))) self.table.setItem(i,0,i_item) def save_plot(self): file_choices = "PNG (*.png)|*.png" path = unicode(QFileDialog.getSaveFileName(self, 'Save file', '', file_choices)) if path: self.canvas.print_figure(path, dpi=self.dpi) self.statusBar().showMessage('Saved to %s' % path, 2000) def on_about(self): msg = """A design tool using PyQt with matplotlib. """ QMessageBox.about(self, "About the software", msg.strip()) def tableHeaderSort(self): #print "Sort header" case_num = int(self.case_cbox.currentIndex()) for i,pinobj in enumerate(self.pinobjects[case_num]): #for i,pinobj in enumerate(self.circlelist): #item = QTableWidgetItem(str(self.table.item(i,0).text())) index = int(self.table.item(i,0).text()) item = QTableWidgetItem(str(self.pinobjects[case_num][index].coord)) #item = QTableWidgetItem(str(self.circlelist[index].coord)) self.table.setVerticalHeaderItem(i,item) def tableSelectRow(self,i): index = next(j for j in range(self.table.rowCount()) if int(self.table.item(j,0).text()) == i) self.table.selectRow(index) def pinSelect(self,i): index = int(self.table.item(i,0).text()) self.mark_pin(index) def on_click(self, event): # The event received here is of the type # matplotlib.backend_bases.PickEvent # # It carries lots of information, of which we're using # only a small amount here. # #print event.x,event.y #if qApp.keyboardModifiers() & Qt.ControlModifier: # ctrl+click # remove = False #else: # remove = True case_num = int(self.case_cbox.currentIndex()) if event.button is 1: #print event.xdata, event.ydata i = np.nan try: # check if any circle is selected and return the index i = next(i for i,cobj in enumerate(self.pinobjects[case_num]) #i = next(i for i,cobj in enumerate(self.circlelist) if cobj.is_clicked(event.xdata,event.ydata)) except: pass if i >= 0: # A Circle is selected #print self.circlelist[i].coord self.tableSelectRow(i) #self.table.selectRow(i) #print i,self.circlelist[i].x,self.circlelist[i].y self.mark_pin(i) self.pinselection_index = i j = self.halfsym_pin(i) def halfsym_pin(self,i): case_num = int(self.case_cbox.currentIndex()) pos = self.pinobjects[case_num][i].pos sympos = list(reversed(pos)) j = next(k for k,po in enumerate(self.pinobjects[case_num]) if po.pos == sympos) return j def mark_pin(self,i): case_num = int(self.case_cbox.currentIndex()) d = self.pinobjects[case_num][i].circle.get_radius()*2*1.25 x = self.pinobjects[case_num][i].x-d/2 y = self.pinobjects[case_num][i].y-d/2 #d = self.circlelist[i].circle.get_radius()*2*1.25 #x = self.circlelist[i].x-d/2 #y = self.circlelist[i].y-d/2 if hasattr(self,'clickpatch'): # Remove any previously selected circles try: self.clickpatch.remove() except: pass #self.clickrect = mpatches.Rectangle((x,y), d, d,hatch='.', # fc=(1,1,1),alpha=1.0,ec=(1, 0, 0)) #self.clickrect = mpatches.Rectangle((x,y), d, d, # fc=(1,1,1),Fill=False,ec=(0, 0, 0)) r = self.pinobjects[case_num][i].circle.get_radius()*1.3 x = self.pinobjects[case_num][i].x y = self.pinobjects[case_num][i].y #r = self.circlelist[i].circle.get_radius()*1.3 #x = self.circlelist[i].x #y = self.circlelist[i].y self.clickpatch = mpatches.Circle((x,y), r, fc=(1,1,1), alpha=1.0, ec=(0.2, 0.2, 0.2)) self.clickpatch.set_linestyle('solid') self.clickpatch.set_fill(False) self.clickpatch.set_linewidth(2.0) self.axes.add_patch(self.clickpatch) self.canvas.draw() def enr_add(self): halfsym = True case_num = int(self.case_cbox.currentIndex()) ivec=[] ivec.append(self.pinselection_index) if halfsym: isym = self.halfsym_pin(ivec[0]) if isym != ivec[0]: ivec.append(isym) for i in ivec: #print "Increase enrichment for pin " + str(i) pinEnr = self.pinobjects[case_num][i].ENR pinBA = self.pinobjects[case_num][i].BA #pinEnr = self.circlelist[i].ENR #pinBA = self.circlelist[i].BA for j,x in enumerate(self.enrpinlist): if np.isnan(x.BA): x.BA = 0.0 if x.ENR == pinEnr and x.BA == pinBA: break if j < len(self.enrpinlist)-1: self.__pinenr_update(i,j+1) def enr_sub(self): halfsym = True case_num = int(self.case_cbox.currentIndex()) ivec=[] ivec.append(self.pinselection_index) if halfsym: isym = self.halfsym_pin(ivec[0]) if isym != ivec[0]: ivec.append(isym) for i in ivec: #print "Decrease enrichment for pin " + str(i) pinEnr = self.pinobjects[case_num][i].ENR pinBA = self.pinobjects[case_num][i].BA #pinEnr = self.circlelist[i].ENR #pinBA = self.circlelist[i].BA for j,x in enumerate(self.enrpinlist): if np.isnan(x.BA): x.BA = 0.0 if x.ENR == pinEnr and x.BA == pinBA: break if j > 0: self.__pinenr_update(i,j-1) #enrArray = [x.ENR for x in self.enrpinlist][::-1] # Reverse order #print enrArray def __pinenr_update(self,i,j): #i = self.pinselection_index case_num = int(self.case_cbox.currentIndex()) self.pinobjects[case_num][i].LFU = j+1 self.pinobjects[case_num][i].ENR = self.enrpinlist[j].ENR #self.circlelist[i].ENR = self.enrpinlist[j].ENR if np.isnan(self.enrpinlist[j].BA): self.pinobjects[case_num][i].BA = 0.0 #self.circlelist[i].BA = 0.0 else: self.pinobjects[case_num][i].BA = self.enrpinlist[j].BA #self.circlelist[i].BA = self.enrpinlist[j].BA fc = self.enrpinlist[j].circle.get_facecolor() text = self.enrpinlist[j].text.get_text() if str(self.param_cbox.currentText()) == 'ENR': self.pinobjects[case_num][i].text.remove() self.pinobjects[case_num][i].set_text(text) #self.circlelist[i].set_text(text) self.pinobjects[case_num][i].circle.set_facecolor(fc) #self.circlelist[i].circle.set_facecolor(fc) self.dataobj.cases[case_num].qcalc[0].LFU = self.__lfumap(case_num) self.canvas.draw() def __lfumap(self,case_num): print "Creating LFU map" #case_num = int(self.case_cbox.currentIndex()) #pyqt_trace() # Initialize new LFU map and fill with zeros LFU_old = self.dataobj.cases[case_num].data.LFU LFU = np.zeros((LFU_old.shape[0],LFU_old.shape[1])); k = 0 for i in range(LFU.shape[0]): for j in range(LFU.shape[1]): if LFU_old[i,j] > 0: LFU[i,j] = self.pinobjects[case_num][k].LFU k += 1 return LFU def quick_calc(self,case_num): print "Performing quick calculation..." LFU = self.__lfumap(case_num) self.dataobj.cases[case_num].qcalc[0].LFU = LFU self.dataobj.cases[case_num].quickcalc() print "Done" # case_num = int(self.case_cbox.currentIndex()) # self.dataobj.cases[case_num].pertcalc() #pyqt_trace() def fig_update(self): """ Redraw figure and update values """ #self.on_draw() self.axes.clear() self.draw_fuelmap() self.set_pinvalues() def on_draw(self): """ Setup the figure axis """ # clear the axes and redraw the plot anew # #self.fig.clf() self.axes.clear() self.axes.axis('equal') #self.axes.set_xlim(0,1) #self.axes.set_ylim(0,1) #self.axes.axis('equal') #self.axes.set_position([0,0,1,1]) #self.axes.set_xlim(0,1.2) #self.axes.set_ylim(0,1) self.axes.set_position([0,0,1,1]) #self.axes.set_visible(False) self.axes.set_frame_on(False) self.axes.get_xaxis().set_visible(False) self.axes.get_yaxis().set_visible(False) #Tracer()() #self.axes.grid(self.grid_cb.isChecked()) #xmax = self.slider.value() #self.axes.set_xlim(0,xmax) #self.axes.axis('equal') #Tracer()() #self.canvas.draw() def draw_fuelmap(self): """ Draw fuel map """ #print "draw fuel map" from map_s96o2 import s96o2 from map_a10xm import a10xm #print "draw fuel map" self.fig.set_facecolor((1,1,0.8784)) # Draw outer rectangle rect = mpatches.Rectangle((0.035,0.035), 0.935, 0.935, fc=(0.8,0.898,1),ec=(0.3, 0.3, 0.3)) self.axes.add_patch(rect) # Draw control rods rodrect_v = mpatches.Rectangle((0.011,0.13), 0.045, 0.77, ec=(0.3, 0.3, 0.3)) rodrect_v.set_fill(False) self.axes.add_patch(rodrect_v) #self.axes.hlines(0.17,0.011,0.056) pp = [[0.011, 0.17], [0.056, 0.17]] poly = mpatches.Polygon(pp) poly.set_closed(False) self.axes.add_patch(poly) pp = [[0.011, 0.86], [0.056, 0.86]] poly = mpatches.Polygon(pp) poly.set_closed(False) self.axes.add_patch(poly) rodrect_h = mpatches.Rectangle((0.1,0.95), 0.77, 0.045, ec=(0.3, 0.3, 0.3)) rodrect_h.set_fill(False) self.axes.add_patch(rodrect_h) pp = [[0.14, 0.95], [0.14, 0.995]] poly = mpatches.Polygon(pp) poly.set_closed(False) self.axes.add_patch(poly) pp = [[0.83, 0.95], [0.83, 0.995]] poly = mpatches.Polygon(pp) poly.set_closed(False) self.axes.add_patch(poly) # a fancy box with round corners (pad). p_fancy = mpatches.FancyBboxPatch((0.12, 0.12), 0.77, 0.77, boxstyle="round,pad=0.04", #fc=(0.85,1,1), fc=(1,1,1), ec=(0.3, 0.3, 0.3)) p_fancy.set_linewidth(4.0) self.axes.add_patch(p_fancy) if self.dataobj.data.fuetype == 'SVEA-96': s96o2(self) elif self.dataobj.data.fuetype == 'A10XM': a10xm(self) # Draw symmetry line #pp = [[0.035, 0.965], [0.965, 0.035]] #poly = mpatches.Polygon(pp) #poly.set_closed(False) #self.axes.add_patch(poly) def startpoint(self,case_id): voi_val = int(self.voi_cbox.currentText()) vhi_val = int(self.vhi_cbox.currentText()) type_val = str(self.type_cbox.currentText()) case = self.cas.cases[case_id] if type_val == 'CCl': idx0 = case.findpoint(tfu=293) voi = case.statepts[idx0].voi vhi = case.statepts[idx0].vhi voi_index = [i for i,v in enumerate(self.voilist) if int(v) == voi][0] vhi_index = [i for i,v in enumerate(self.vhilist) if int(v) == vhi][0] self.voi_cbox.setCurrentIndex(voi_index) self.vhi_cbox.setCurrentIndex(vhi_index) else: idx0 = case.findpoint(voi=voi_val,vhi=vhi_val) return idx0 def create_main_frame(self): self.main_frame = QWidget() # Create the mpl Figure and FigCanvas objects. # 5x4 inches, 100 dots-per-inch # self.dpi = 100 self.fig = Figure((6, 5), dpi=self.dpi, facecolor=None) #self.fig = Figure((6, 5), dpi=self.dpi, facecolor=(1,1,1)) self.canvas = FigureCanvas(self.fig) self.canvas.mpl_connect('button_press_event',self.on_click) self.canvas.setParent(self.main_frame) self.canvas.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) self.canvas.setMinimumWidth(500) self.canvas.setMinimumHeight(416) cvbox = QVBoxLayout() cvbox.addWidget(self.canvas) canvasGbox = QGroupBox() canvasGbox.setStyleSheet("QGroupBox { background-color: rgb(200, 200,\ 200); border:1px solid gray; border-radius:5px;}") canvasGbox.setLayout(cvbox) # Since we have only one plot, we can use add_axes # instead of add_subplot, but then the subplot # configuration tool in the navigation toolbar wouldn't # work. # self.axes = self.fig.add_subplot(111) # Bind the 'pick' event for clicking on one of the bars # #self.canvas.mpl_connect('pick_event', self.on_pick) # Create the navigation toolbar, tied to the canvas # #self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) # Other GUI controls # #self.textbox = QLineEdit() #self.textbox.setMinimumWidth(200) #self.connect(self.textbox, SIGNAL('editingFinished ()'), self.on_draw) #self.draw_button = QPushButton("Draw") #self.connect(self.draw_button, SIGNAL('clicked()'), self.on_plot) #self.grid_cb = QCheckBox("Show Grid") #self.grid_cb.setChecked(True) #self.connect(self.grid_cb, SIGNAL('stateChanged(int)'), self.on_draw) #slider_label = QLabel('X-max:') #self.slider = QSlider(Qt.Horizontal) #self.slider.setRange(1, 75) #self.slider.setValue(65) #self.slider.setTracking(True) #self.slider.setTickPosition(QSlider.TicksBothSides) #self.connect(self.slider, SIGNAL('valueChanged(int)'), self.on_draw) param_label = QLabel('Parameter:') self.param_cbox = QComboBox() paramlist = ['ENR','FINT','EXP','BTF','BTFP','XFL1','XFL2','ROD','LOCK'] for i in paramlist: self.param_cbox.addItem(i) #self.connect(self.param_cbox, SIGNAL('currentIndexChanged(int)'), self.on_plot) param_hbox = QHBoxLayout() param_hbox.addWidget(param_label) param_hbox.addWidget(self.param_cbox) self.connect(self.param_cbox, SIGNAL('currentIndexChanged(int)'), self.set_pinvalues) case_label = QLabel('Case number:') self.case_cbox = QComboBox() #caselist = ['1', '2', '3'] #for i in caselist: # self.case_cbox.addItem(i) case_hbox = QHBoxLayout() case_hbox.addWidget(case_label) case_hbox.addWidget(self.case_cbox) #self.connect(self.case_cbox, SIGNAL('currentIndexChanged(int)'), self.set_pinvalues) #self.connect(self.case_cbox, SIGNAL('currentIndexChanged(int)'), self.fig_update) point_label = QLabel('Point number:') self.point_sbox = QSpinBox() self.point_sbox.setMinimum(0) self.point_sbox.setMaximum(10000) point_hbox = QHBoxLayout() point_hbox.addWidget(point_label) point_hbox.addWidget(self.point_sbox) self.connect(self.point_sbox, SIGNAL('valueChanged(int)'), self.set_pinvalues) self.enr_plus_button = QPushButton("+ enr") self.enr_minus_button = QPushButton("- enr") enr_hbox = QHBoxLayout() enr_hbox.addWidget(self.enr_minus_button) enr_hbox.addWidget(self.enr_plus_button) self.connect(self.enr_plus_button, SIGNAL('clicked()'), self.enr_add) self.connect(self.enr_minus_button, SIGNAL('clicked()'), self.enr_sub) self.calc_quick_button = QPushButton("Quick calc") self.calc_full_button = QPushButton("Full calc") calc_hbox = QHBoxLayout() calc_hbox.addWidget(self.calc_quick_button) calc_hbox.addWidget(self.calc_full_button) self.connect(self.calc_quick_button, SIGNAL('clicked()'), self.quick_calc) type_label = QLabel('Type:') self.type_cbox = QComboBox() typelist = ['Hot', 'HCr', 'CCl', 'CCr'] for i in typelist: self.type_cbox.addItem(i) #self.connect(self.type_cbox, SIGNAL('currentIndexChanged(int)'), self.on_index) voi_label = QLabel('VOI:') self.voi_cbox = QComboBox() self.voilist = ['0', '40', '80'] for i in self.voilist: self.voi_cbox.addItem(i) # Determine voi index #voi = self.cas.cases[self.case_id_current].statepts[0].voi #voi_index = [i for i,v in enumerate(self.voilist) if int(v) == voi] #voi_index = voi_index[0] #self.voi_cbox.setCurrentIndex(voi_index) #self.connect(self.voi_cbox, SIGNAL('currentIndexChanged(int)'), self.on_plot) vhi_label = QLabel('VHI:') self.vhi_cbox = QComboBox() self.vhilist = ['0', '40', '80'] for i in self.vhilist: self.vhi_cbox.addItem(i) # Determine vhi index #vhi = self.cas.cases[self.case_id_current].statepts[0].vhi #vhi_index = [i for i,v in enumerate(self.vhilist) if int(v) == vhi] #vhi_index = vhi_index[0] #self.vhi_cbox.setCurrentIndex(vhi_index) #self.connect(self.vhi_cbox, SIGNAL('currentIndexChanged(int)'), self.on_plot) #self.case_cbox.setWhatsThis("What is this?") #self.connect(self.case_cbox, SIGNAL('activated(QString)'), self.on_case) #self.connect(self.case_cbox, SIGNAL('currentIndexChanged(int)'), self.on_plot) #Tracer()() # Define table widget self.table = QTableWidget() self.table.setRowCount(100) self.table.setColumnCount(4) #self.table.verticalHeader().hide() self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch) self.table.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Minimum) self.table.setMinimumWidth(180) self.table.setHorizontalHeaderLabels(('Index','EXP','FINT','BTF')) self.table.setSortingEnabled(True) self.table.setColumnHidden(0,True) #self.connect(self.table.horizontalHeader(),SIGNAL('QHeaderView.sortIndicatorChanged(int)'),self.openFile) self.connect(self.table.horizontalHeader(),SIGNAL('sectionClicked(int)'),self.tableHeaderSort) self.connect(self.table.verticalHeader(),SIGNAL('sectionClicked(int)'),self.pinSelect) #self.connect(self.table,SIGNAL('cellClicked(int,int)'),self.pinSelect) #self.connect(self.table,SIGNAL('currentChanged(int)'),self.pinSelect) #Tracer()() self.table.cellActivated.connect(self.pinSelect) self.table.cellClicked.connect(self.pinSelect) #self.table.selectionModel().selectionChanged.connect(self.pinSelect) tvbox = QVBoxLayout() tvbox.addWidget(self.table) tableGbox = QGroupBox() tableGbox.setStyleSheet("QGroupBox { background-color: rgb(200, 200,\ 200); border:1px solid gray; border-radius:5px;}") tableGbox.setLayout(tvbox) #self.hview = QHeaderView #self.tableview = QTableView() #self.connect(self.table.horizontalHeader().sectionClicked(), SIGNAL('logicalIndex(int)'),self.openFile) #self.connect(QHeaderView.sortIndicatorChanged(), SIGNAL('logicalIndex(int)'),self.openFile) #self.setpincoords() self.table.resizeColumnsToContents() #Tracer()() # # Layout with box sizers # vbox = QVBoxLayout() vbox.addLayout(param_hbox) vbox.addLayout(case_hbox) vbox.addLayout(point_hbox) vbox.addLayout(enr_hbox) vbox.addLayout(calc_hbox) #spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) #vbox.addItem(spacerItem) vbox.addStretch(1) groupbox = QGroupBox() groupbox.setStyleSheet("QGroupBox { background-color: rgb(200, 200,\ 200); border:1px solid gray; border-radius:5px;}") groupbox.setLayout(vbox) #for w in [ self.textbox, self.draw_button, self.grid_cb, # slider_label, self.slider]: #for w in [ type_label, self.type_cbox, voi_label, self.voi_cbox, # vhi_label, self.vhi_cbox]: # # vbox.addWidget(w) # vbox.setAlignment(w, Qt.AlignHCenter) #self.bundle = Bundle() #self.bundle.setParent(self.main_frame) #Tracer()() hbox = QHBoxLayout() #hbox.addWidget(self.bundle) #vbox.addLayout(hbox) #vbox.addWidget(self.canvas) #hbox2.addWidget(self.mpl_toolbar) spacerItemH = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) #hbox.addLayout(vbox) hbox.addWidget(groupbox) #hbox.addItem(spacerItemH) #hbox.addWidget(self.canvas) hbox.addWidget(canvasGbox) #hbox.addItem(spacerItemH) hbox.addWidget(tableGbox) #hbox.addWidget(self.table) #hbox.addItem(spacerItemH) self.main_frame.setLayout(hbox) self.setCentralWidget(self.main_frame) #Tracer()() def create_status_bar(self): self.status_text = QLabel("Main window") self.statusBar().addWidget(self.status_text, 1) def create_menu(self): self.file_menu = self.menuBar().addMenu("&File") save_settings_action = self.create_action("&Save settings...", shortcut="Ctrl+E", slot=self.save_plot, tip="Save settings") quit_action = self.create_action("&Quit", slot=self.close, shortcut="Ctrl+Q", tip="Close the application") open_file_action = self.create_action("&Open file...", slot=self.openFile, shortcut="Ctrl+L", tip="Open file") save_data_action = self.create_action("&Save data...", slot=self.saveData, shortcut="Ctrl+S", tip="Save data to file") self.add_actions(self.file_menu, (open_file_action, save_data_action, save_settings_action, None, quit_action)) self.edit_menu = self.menuBar().addMenu("&Edit") preferences = self.create_action("Preferences...", tip="Preferences...") self.add_actions(self.edit_menu, (None, preferences)) self.tools_menu = self.menuBar().addMenu("&Tools") plot_action = self.create_action("Plot...", tip="Plot...", slot=self.plotWin) btf_action = self.create_action("BTF...", tip="BTF...") casmo_action = self.create_action("CASMO...", tip="CASMO...") data_action = self.create_action("Fuel data...", tip="Fuel data...") table_action = self.create_action("Point table...", tip="Point table...") optim_action = self.create_action("Optimization...", tip="BTF optimization...") egv_action = self.create_action("EGV...", tip="EGV...") self.add_actions(self.tools_menu, (plot_action, btf_action, casmo_action, data_action, table_action, optim_action, egv_action)) self.help_menu = self.menuBar().addMenu("&Help") about_action = self.create_action("&About", shortcut='F1', slot=self.on_about, tip='About the demo') self.add_actions(self.help_menu, (about_action,)) def create_toolbar(self): exitAction = QAction(QIcon('icons/exit-icon_32x32.png'), 'Exit', self) #exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) fileAction = QAction(QIcon('icons/open-file-icon_32x32.png'), 'Open file', self) fileAction.setStatusTip('Open file') fileAction.triggered.connect(self.openFile) settingsAction = QAction(QIcon('icons/preferences-icon_32x32.png'), 'Settings', self) settingsAction.setStatusTip('Settings') plotAction = QAction(QIcon('icons/diagram-icon_32x32.png'), 'Plot', self) plotAction.setStatusTip('Open plot window') plotAction.triggered.connect(self.plotWin) toolbar = self.addToolBar('Toolbar') toolbar.addAction(fileAction) toolbar.addAction(settingsAction) toolbar.addAction(plotAction) toolbar.addAction(exitAction) toolbar.setMovable(False) toolbar.setFloatable(True) toolbar.setAutoFillBackground(False) def add_actions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def create_action( self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action def closeEvent(self, event): # Write window size and position to config file self.settings.beginGroup("MainWindow") self.settings.setValue("size", QVariant(self.size())) self.settings.setValue("pos", QVariant(self.pos())) self.settings.endGroup() print "Good bye!"
class figureViewDialog(QtGui.QDialog): def __init__(self, titles, images, windowTitle, parent=None): super(figureViewDialog, self).__init__(parent) self.setWindowFlags( QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint) self.figure = plt.Figure() self.canvas = FigureCanvas(self.figure) self.canvasHeight = self.canvas.height() self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.setStyleSheet('background-image:url(./images/b1.png); background-attachment: fixed; color: rgb(70, 0, 0);') self.images = images self.titles = titles self.setStyleSheet('background-image:url(./images/kb.png); background-attachment: fixed; color: rgb(70, 0, 0);') font = QtGui.QFont() font.setBold(True) font.setPointSize(9) font.setFamily('Nirmala UI') buttonsFrame = QtGui.QFrame() buttonsFrame.setStyleSheet('background-image:url(./images/b1.png); background-attachment: fixed; color: rgb(70, 0, 0);') buttonsFrame.setFixedHeight(50) buttonsLayout = QtGui.QHBoxLayout() numOfButtons = len(titles) self.buttons = [] for i in range(numOfButtons): newButton = QtGui.QPushButton() newButton.setMinimumHeight(31) newButton.setFont(font) newButton.setStyleSheet('background-image:url(./images/kb.png); background-attachment: fixed; ' 'color: rgb(70, 0, 0);') newButton.setAutoDefault(False) buttonsLayout.addWidget(newButton) self.buttons.append(newButton) buttonsFrame.setLayout(buttonsLayout) self.lblNoti = QtGui.QLabel() font = QtGui.QFont() font.setBold(True) font.setPointSize(8) font.setFamily('Nirmala UI') self.lblNoti.setFont(font) self.setStyleSheet('QLabel {color: #8c4600;}') self.lblNoti.setText('') self.lblNoti.setFixedHeight(15) self.lblNoti.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) lblFrame = QtGui.QFrame() lblFrame.setStyleSheet( 'background-image:url(./images/b1.png); background-attachment: fixed; color: rgb(70, 0, 0);') lblFrameLayout = QtGui.QHBoxLayout() lblFrame.setStyleSheet('QFrame {background-color: white;}') self.lblHead = QtGui.QLabel() font = QtGui.QFont() font.setPointSize(26) font.setFamily('Baskerville Old Face') self.lblHead.setFont(font) self.lblHead.setStyleSheet('QLabel {color: #8c4600;}') self.lblHead.setText('DHAROHAR') self.lblHead.setFixedHeight(25) self.lblHead.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) lblFrameLayout.addWidget(self.lblHead) lblFrame.setLayout(lblFrameLayout) topFrame = QtGui.QFrame() topFrame.setStyleSheet( 'background-image:url(./images/b1.png); background-attachment: fixed; color: rgb(70, 0, 0);') topFrame.setMaximumHeight(55) toplayout = QtGui.QHBoxLayout() toplayout.addWidget(self.toolbar) toplayout.addWidget(lblFrame) topFrame.setLayout(toplayout) self.canvas.setMinimumHeight(500) mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(topFrame) mainLayout.addWidget(self.canvas) mainLayout.addWidget(buttonsFrame) mainLayout.addWidget(self.lblNoti) self.setLayout(mainLayout) self.setWindowTitle(windowTitle) self.connections() self.plot() def connections(self): if len(self.titles) == 6: self.buttons[0].clicked.connect(self.saveFigure1) self.buttons[1].clicked.connect(self.saveFigure2) self.buttons[2].clicked.connect(self.saveFigure3) self.buttons[3].clicked.connect(self.saveFigure4) self.buttons[4].clicked.connect(self.saveFigure5) self.buttons[5].clicked.connect(self.saveFigure6) elif len(self.titles) == 5: self.buttons[0].clicked.connect(self.saveFigure1) self.buttons[1].clicked.connect(self.saveFigure2) self.buttons[2].clicked.connect(self.saveFigure3) self.buttons[3].clicked.connect(self.saveFigure4) self.buttons[4].clicked.connect(self.saveFigure5) elif len(self.titles) == 4: self.buttons[0].clicked.connect(self.saveFigure1) self.buttons[1].clicked.connect(self.saveFigure2) self.buttons[2].clicked.connect(self.saveFigure3) self.buttons[3].clicked.connect(self.saveFigure4) elif len(self.titles) == 3: self.buttons[0].clicked.connect(self.saveFigure1) self.buttons[1].clicked.connect(self.saveFigure2) self.buttons[2].clicked.connect(self.saveFigure3) elif len(self.titles) == 2: self.buttons[0].clicked.connect(self.saveFigure1) self.buttons[1].clicked.connect(self.saveFigure2) elif len(self.titles) == 1: self.buttons[0].clicked.connect(self.saveFigure1) def saveFigure1(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[0].setEnabled(False) self.buttons[0].setFlat(True) plt.imsave(filename, self.images[0], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[0] + "' Saved.") self.buttons[0].setEnabled(True) self.buttons[0].setFlat(False) def saveFigure2(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[1].setEnabled(False) self.buttons[1].setFlat(True) plt.imsave(filename, self.images[1], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[1] + "' Saved.") self.buttons[1].setEnabled(True) self.buttons[1].setFlat(False) def saveFigure3(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[2].setEnabled(False) self.buttons[2].setFlat(True) plt.imsave(filename, self.images[2], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[2] + "' Saved.") self.buttons[2].setEnabled(True) self.buttons[2].setFlat(False) def saveFigure4(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[3].setEnabled(False) self.buttons[3].setFlat(True) plt.imsave(filename, self.images[3], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[3] + "' Saved.") self.buttons[3].setEnabled(True) self.buttons[3].setFlat(False) def saveFigure5(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[4].setEnabled(False) self.buttons[4].setFlat(True) plt.imsave(filename, self.images[4], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[4] + "' Saved.") self.buttons[4].setEnabled(True) self.buttons[4].setFlat(False) def saveFigure6(self): filename = str(QtGui.QFileDialog.getSaveFileName(self, 'Save file', '', 'Image Files(*.png *.jpeg *.jpg *.tiff ' '*.bmp *.tif)', None)) if not filename: self.lblNoti.setText("To save a figure, provide a file name and click 'Save'.") else: self.lblNoti.setText('Saving... Please wait...') self.buttons[5].setEnabled(False) self.buttons[5].setFlat(True) plt.imsave(filename, self.images[5], cmap='gray') self.lblNoti.setText("Figure '" + self.titles[5] + "' Saved.") self.buttons[5].setEnabled(True) self.buttons[5].setFlat(False) def plot(self): R = 1 C = len(self.titles) for i in range(1, C + 1): fig = self.figure.add_subplot(R, C, i) fig.clear() fig.imshow(self.images[i - 1], cmap='gray') fig.set_title(self.titles[i - 1]) fig.axis('off') self.buttons[i - 1].setText("Save - '" + self.titles[i - 1] + "'") self.canvas.draw()
class StreamViewerWidget(QtGui.QWidget): """Shows the entire signal and allows the user to navigate through it. Provides an scrollable selector over the entire signal. Attributes: xmin: Selector lower limit (measured in h-axis units). xmax: Selector upper limit (measured in h-axis units). step: Selector length (measured in h-axis units). """ trace_selected = QtCore.Signal(int) selection_made = QtCore.Signal(bool) def __init__(self, parent, stream=None): super(StreamViewerWidget, self).__init__(parent) self.fig = plt.figure() self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.canvas.setFocus() self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.graphArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) # Animation related attrs. self.background = [] self.animated = False self.size = (self.fig.bbox.width, self.fig.bbox.height) # Set TracePlot list self.trace_plots = [] self.stream = None if stream is not None: self.set_stream(stream) # Event handling self.visible_axes = [] self._selected_traces = set() self.shift_pressed = False self.press_selector = None self.fig.canvas.mpl_connect('motion_notify_event', self.on_move) self.fig.canvas.mpl_connect('button_press_event', self.on_press) self.fig.canvas.mpl_connect('key_press_event', self.on_key_press) self.fig.canvas.mpl_connect('key_release_event', self.on_key_release) @property def selected_traces(self): if self.stream is not None: return [self.stream.traces[i] for i in self._selected_traces] return [] def on_move(self, event): axes_selected = False for i, axes in enumerate(self.fig.axes): if axes.get_visible(): ymin, ymax = axes.get_position().ymin, axes.get_position().ymax xmin, xmax = axes.get_position().xmin, axes.get_position().xmax xfig, yfig = self._event_to_fig_coords(event) if ymin <= yfig <= ymax and xmin <= xfig <= xmax: self.canvas.setToolTip(self.stream.traces[i].name) axes_selected = True break if not axes_selected: self.canvas.setToolTip("") def on_key_press(self, event): if event.key == 'control': self.shift_pressed = True def on_key_release(self, event): self.shift_pressed = False def on_press(self, event): trace_selected = False if event.button == 1:# and event.dblclick: for i, ax in enumerate(self.fig.axes): if ax.get_visible(): ymin, ymax = ax.get_position().ymin, ax.get_position().ymax xmin, xmax = ax.get_position().xmin, ax.get_position().xmax xfig, yfig = self._event_to_fig_coords(event) if ymin <= yfig <= ymax and xmin <= xfig <= xmax: trace_selected = True if self.shift_pressed: if self._selected_traces: self.trace_selected.emit(i) self.selection_made.emit(True) self._selected_traces.add(i) else: self.trace_selected.emit(i) self.selection_made.emit(True) self._selected_traces = {i} break # if the user clicked out of any trace (and he's not using shift), then deselect all if not trace_selected and not self.shift_pressed: self._selected_traces = set() self.selection_made.emit(False) # Now update selection status on plots for i, plot in enumerate(self.trace_plots): plot.set_selected(i in self._selected_traces) self.draw() def _event_to_fig_coords(self, event): inv = self.fig.transFigure.inverted() return inv.transform((event.x, event.y)) def set_stream(self, stream): self.stream = stream self._selected_traces = set() # Clear canvas for plot in self.trace_plots: plot.remove() self.trace_plots = [] # Plot stream traces for i, trace in enumerate(self.stream.traces): self.trace_plots.append(TracePlot(self, trace, fig_nrows=len(stream), ax_pos=i + 1)) # Draw canvas self.subplots_adjust() self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) self.draw() def refresh_stream_data(self): for plot in self.trace_plots: plot.update_data() def draw(self): self.canvas.draw() #self.draw_animate() def draw_animate(self): size = self.fig.bbox.width, self.fig.bbox.height if size != self.size: self.size = size self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) self.canvas.restore_region(self.background) for artist in self._get_animated_artists(): if artist.get_visible(): ax = artist.get_axes() if ax is not None: if artist.get_axes().get_visible(): self.fig.draw_artist(artist) else: self.fig.draw_artist(artist) self.canvas.blit(self.fig.bbox) def _get_animated_artists(self): artists = [] for ax in self.fig.axes: artists.extend(ax.images) artists.extend(ax.lines) artists.append(ax.xaxis) artists.append(ax.yaxis) artists.extend(ax.patches) artists.extend(ax.spines.values()) for artist in artists: if artist.get_animated(): yield artist def set_visible(self, value): self.canvas.setVisible(value) def get_visible(self): return self.canvas.isVisible() def remove_trace(self, idx): self.trace_plots.pop(idx).remove() def subplots_adjust(self): visible_subplots = [ax for ax in self.fig.get_axes() if ax.get_visible()] for i, ax in enumerate(visible_subplots): correct_geometry = (len(visible_subplots), 1, i + 1) if correct_geometry != ax.get_geometry(): ax.change_geometry(len(visible_subplots), 1, i + 1) # Adjust space between subplots self.fig.subplots_adjust(left=0.02, right=0.98, bottom=0.02, top=0.98, hspace=0.05) def showEvent(self, event): self.draw() def resizeEvent(self, event): self.draw() def update_markers(self): for plot in self.trace_plots: plot.update_markers() self.draw() def visualize_stream_range(self, start_trace=None, end_trace=None): for i, ax in enumerate(self.fig.axes): ax.set_visible(start_trace <= i < end_trace) self.subplots_adjust() self.canvas.draw()
class StreamViewerWidget(QtGui.QWidget): """Shows the entire signal and allows the user to navigate through it. Provides an scrollable selector over the entire signal. Attributes: xmin: Selector lower limit (measured in h-axis units). xmax: Selector upper limit (measured in h-axis units). step: Selector length (measured in h-axis units). """ trace_selected = QtCore.Signal(int) selection_made = QtCore.Signal(bool) def __init__(self, parent, stream=None): super(StreamViewerWidget, self).__init__(parent) self.fig = plt.figure() self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy( QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.canvas.setFocusPolicy(QtCore.Qt.ClickFocus) self.canvas.setFocus() self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.graphArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) # Animation related attrs. self.background = [] self.animated = False self.size = (self.fig.bbox.width, self.fig.bbox.height) # Set TracePlot list self.trace_plots = [] self.stream = None if stream is not None: self.set_stream(stream) # Event handling self.visible_axes = [] self._selected_traces = set() self.shift_pressed = False self.press_selector = None self.fig.canvas.mpl_connect('motion_notify_event', self.on_move) self.fig.canvas.mpl_connect('button_press_event', self.on_press) self.fig.canvas.mpl_connect('key_press_event', self.on_key_press) self.fig.canvas.mpl_connect('key_release_event', self.on_key_release) @property def selected_traces(self): if self.stream is not None: return [self.stream.traces[i] for i in self._selected_traces] return [] def on_move(self, event): axes_selected = False for i, axes in enumerate(self.fig.axes): if axes.get_visible(): ymin, ymax = axes.get_position().ymin, axes.get_position().ymax xmin, xmax = axes.get_position().xmin, axes.get_position().xmax xfig, yfig = self._event_to_fig_coords(event) if ymin <= yfig <= ymax and xmin <= xfig <= xmax: self.canvas.setToolTip(self.stream.traces[i].name) axes_selected = True break if not axes_selected: self.canvas.setToolTip("") def on_key_press(self, event): if event.key == 'control': self.shift_pressed = True def on_key_release(self, event): self.shift_pressed = False def on_press(self, event): trace_selected = False if event.button == 1: # and event.dblclick: for i, ax in enumerate(self.fig.axes): if ax.get_visible(): ymin, ymax = ax.get_position().ymin, ax.get_position().ymax xmin, xmax = ax.get_position().xmin, ax.get_position().xmax xfig, yfig = self._event_to_fig_coords(event) if ymin <= yfig <= ymax and xmin <= xfig <= xmax: trace_selected = True if self.shift_pressed: if self._selected_traces: self.trace_selected.emit(i) self.selection_made.emit(True) self._selected_traces.add(i) else: self.trace_selected.emit(i) self.selection_made.emit(True) self._selected_traces = {i} break # if the user clicked out of any trace (and he's not using shift), then deselect all if not trace_selected and not self.shift_pressed: self._selected_traces = set() self.selection_made.emit(False) # Now update selection status on plots for i, plot in enumerate(self.trace_plots): plot.set_selected(i in self._selected_traces) self.draw() def _event_to_fig_coords(self, event): inv = self.fig.transFigure.inverted() return inv.transform((event.x, event.y)) def set_stream(self, stream): self.stream = stream self._selected_traces = set() # Clear canvas for plot in self.trace_plots: plot.remove() self.trace_plots = [] # Plot stream traces for i, trace in enumerate(self.stream.traces): self.trace_plots.append( TracePlot(self, trace, fig_nrows=len(stream), ax_pos=i + 1)) # Draw canvas self.subplots_adjust() self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) self.draw() def refresh_stream_data(self): for plot in self.trace_plots: plot.update_data() def draw(self): self.canvas.draw() #self.draw_animate() def draw_animate(self): size = self.fig.bbox.width, self.fig.bbox.height if size != self.size: self.size = size self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) self.canvas.restore_region(self.background) for artist in self._get_animated_artists(): if artist.get_visible(): ax = artist.get_axes() if ax is not None: if artist.get_axes().get_visible(): self.fig.draw_artist(artist) else: self.fig.draw_artist(artist) self.canvas.blit(self.fig.bbox) def _get_animated_artists(self): artists = [] for ax in self.fig.axes: artists.extend(ax.images) artists.extend(ax.lines) artists.append(ax.xaxis) artists.append(ax.yaxis) artists.extend(ax.patches) artists.extend(ax.spines.values()) for artist in artists: if artist.get_animated(): yield artist def set_visible(self, value): self.canvas.setVisible(value) def get_visible(self): return self.canvas.isVisible() def remove_trace(self, idx): self.trace_plots.pop(idx).remove() def subplots_adjust(self): visible_subplots = [ ax for ax in self.fig.get_axes() if ax.get_visible() ] for i, ax in enumerate(visible_subplots): correct_geometry = (len(visible_subplots), 1, i + 1) if correct_geometry != ax.get_geometry(): ax.change_geometry(len(visible_subplots), 1, i + 1) # Adjust space between subplots self.fig.subplots_adjust(left=0.02, right=0.98, bottom=0.02, top=0.98, hspace=0.05) def showEvent(self, event): self.draw() def resizeEvent(self, event): self.draw() def update_markers(self): for plot in self.trace_plots: plot.update_markers() self.draw() def visualize_stream_range(self, start_trace=None, end_trace=None): for i, ax in enumerate(self.fig.axes): ax.set_visible(start_trace <= i < end_trace) self.subplots_adjust() self.canvas.draw()
class miVentana(QtGui.QWidget): def __init__(self): super(miVentana, self).__init__() self.titulo = 'Toda Informacion' self.ejeX = 'Todos' self.ejeY = 'Tiempo' self.miFilaAuxiliar = Queue() self.miTarjetaAdquisicion = TarjetaAdquisicion(self.miFilaAuxiliar) self.puertoConectadoExitoso = self.miTarjetaAdquisicion.reconociPuerto time.sleep(2) self.initUI() self.estadoAuxiliar = False self.indices = { 'Todos': [0, '$[V] [A] [C] [rpm]$'], 'Tiempo': [0, '$t [s]$'], 'Voltaje': [1, 'v [V]'], 'Corriente': [2, '$I [A]$'], 'Temperatura': [3, '$T [C]$'], 'rpm': [4, '$\omega [rpm]$'] } def initUI(self): ## PARAMETROS DEL MOTOR self.miTituloIzquierdo = QtGui.QLabel('Datos de Placa') self.parametrosOrganizacionales = QtGui.QHBoxLayout() self.parametrosDePlaca1 = QtGui.QHBoxLayout() self.parametrosDePlaca2 = QtGui.QHBoxLayout() self.parametrosDePlaca3 = QtGui.QHBoxLayout() self.miMotor = QtGui.QLabel('Motor:') self.miDataMotor = QtGui.QLineEdit('Motor-001') self.parametrosOrganizacionales.addWidget(self.miMotor) self.parametrosOrganizacionales.addWidget(self.miDataMotor) self.miPotenciaPlaca = QtGui.QLabel('Potencia Nominal [HP]:') self.miDatoPotenciaPlaca = QtGui.QLineEdit(str(85)) self.parametrosDePlaca1.addWidget(self.miPotenciaPlaca) self.parametrosDePlaca1.addWidget(self.miDatoPotenciaPlaca) self.miTensionNominal = QtGui.QLabel('Voltaje Nominal [V]:') self.miDataTensionNominal = QtGui.QLineEdit(str(350)) self.parametrosDePlaca2.addWidget(self.miTensionNominal) self.parametrosDePlaca2.addWidget(self.miDataTensionNominal) self.miVelocidadNominal = QtGui.QLabel('Velocidad Nominal [rpm]:') self.miDataVelocidadNominal = QtGui.QLineEdit(str(3500)) self.parametrosDePlaca3.addWidget(self.miVelocidadNominal) self.parametrosDePlaca3.addWidget(self.miDataVelocidadNominal) # MENU SUPERIOS extractAction = QtGui.QAction('&SALIR', self) extractAction.setShortcut('Ctrl+Q') extractAction.setStatusTip('Salir de la aplicacion') extractAction.triggered.connect(self.closeApplication) ## CONTROL EJECUCIÓN self.botonDeInicio = QtGui.QPushButton("Importar Datos") self.botonDeCancel = QtGui.QPushButton("Detener") self.botonDeInicializacion = QtGui.QPushButton("Descartar Prueba") self.botonParaPDF = QtGui.QPushButton("Exportar Info") #self.botonParaPDF.setStyleSheet("background-color: green") self.botonDeInicializacion.setEnabled(False) self.botonParaPDF.setEnabled(False) self.botonDeCancel.setEnabled(False) self.botonDeInicio.resize(100, 100) self.botonDeCancel.resize(100, 100) #self.botonDeInicio.setMinimumHeight(60) #self.botonDeCancel.setMinimumHeight(60) self.barraControlPrograma = QtGui.QHBoxLayout() self.barraControlPrograma.addWidget(self.botonDeInicio) self.barraControlPrograma.addWidget(self.botonDeCancel) self.barraControlPostPrograma = QtGui.QHBoxLayout() self.barraControlPostPrograma.addWidget(self.botonDeInicializacion) self.barraControlPostPrograma.addWidget(self.botonParaPDF) ## Control de Botones self.botonDeInicio.clicked.connect(self.importarDatos) self.botonDeCancel.clicked.connect(self.detenerDatos) self.botonDeInicializacion.clicked.connect(self.inicializarTodo) self.botonParaPDF.clicked.connect(self.exportarInformacion) # a figure instance to plot on #self.figure = Figure() self.figure = graficaActual.figure(figsize=(15, 5)) # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) self.canvas.resize(500, 800) self.canvas.setMinimumWidth(450) self.canvas.setMaximumWidth(500) self.canvas.setMinimumHeight(350) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) ### CONTROL DE GRAFICA: self.miTituloControlGrafica = QtGui.QLabel( 'Graficar: (Inicio: ' + self.miTarjetaAdquisicion.horaInicioLiteral + ')') self.miLegendaVS = QtGui.QLabel('vs') self.seleccionDeOrdenada = QtGui.QComboBox(self) self.seleccionDeOrdenada.addItem('Todos') self.seleccionDeOrdenada.addItem('Voltaje') self.seleccionDeOrdenada.addItem('Corriente') self.seleccionDeOrdenada.addItem('Temperatura') self.seleccionDeOrdenada.addItem('rpm') self.seleccionDeAbsisa = QtGui.QComboBox(self) self.seleccionDeAbsisa.addItem('Tiempo') self.seleccionDeAbsisa.addItem('Voltaje') self.seleccionDeAbsisa.addItem('Corriente') self.seleccionDeAbsisa.addItem('Temperatura') self.seleccionDeAbsisa.addItem('rpm') self.seleccionDeOrdenada.activated[str].connect( self.actualizarOrdenada) self.seleccionDeAbsisa.activated[str].connect(self.actualizarAbsisa) self.barraControlGrafica = QtGui.QHBoxLayout() self.barraControlGrafica.addWidget(self.seleccionDeOrdenada) self.barraControlGrafica.addWidget(self.miLegendaVS) self.barraControlGrafica.addWidget(self.seleccionDeAbsisa) ## SECCION COMENTARIOS: self.miTituloComentarios = QtGui.QLabel('Comentarios:') self.miComentario = QtGui.QTextEdit() #self.miComentario.setMinimumHeight(50) ## Control de puerto self.miEtiquetaPuerto = QtGui.QLabel('Conectar a:') self.miIntroduccionPuerto = QtGui.QLineEdit('ttyAMA0') ## Adquisicion de datos: self.miDataMotor.editingFinished.connect(self.actualizarIngresoDatos) self.miDatoPotenciaPlaca.editingFinished.connect( self.actualizarIngresoDatos) self.miDataTensionNominal.editingFinished.connect( self.actualizarIngresoDatos) self.miDataVelocidadNominal.editingFinished.connect( self.actualizarIngresoDatos) self.miIntroduccionPuerto.returnPressed.connect( self.intentoIntroducirPuerto) #self.miComentario.textChanged.connect(self.actualizarIngresoDatos) ## GRAFICA IZQUIERDA capaVerticalAuxiliar = QtGui.QVBoxLayout() if not self.puertoConectadoExitoso: self.miEtiquetaPuerto.setText('No conectado, Conectar a:') self.botonDeInicio.setEnabled(False) capaVerticalAuxiliar.addWidget(self.miEtiquetaPuerto) capaVerticalAuxiliar.addWidget(self.miIntroduccionPuerto) capaVerticalAuxiliar.addWidget(self.miTituloIzquierdo) capaVerticalAuxiliar.addLayout(self.parametrosOrganizacionales) capaVerticalAuxiliar.addLayout(self.parametrosDePlaca1) capaVerticalAuxiliar.addLayout(self.parametrosDePlaca2) capaVerticalAuxiliar.addLayout(self.parametrosDePlaca3) capaVerticalAuxiliar.addWidget(self.miTituloControlGrafica) capaVerticalAuxiliar.addLayout(self.barraControlGrafica) capaVerticalAuxiliar.addWidget(self.miTituloComentarios) capaVerticalAuxiliar.addWidget(self.miComentario) capaVerticalAuxiliar.addStretch(1) capaVerticalAuxiliar.addLayout(self.barraControlPostPrograma) capaVerticalAuxiliar.addLayout(self.barraControlPrograma) graficaV = QtGui.QVBoxLayout() graficaV.addWidget(self.toolbar) graficaV.addWidget(self.canvas) layoutHorizontalPrincipal = QtGui.QHBoxLayout() #layoutHorizontalPrincipal.addStretch(1) layoutHorizontalPrincipal.addLayout(capaVerticalAuxiliar) layoutHorizontalPrincipal.addLayout(graficaV) self.setMinimumHeight(430) self.setLayout(layoutHorizontalPrincipal) self.setGeometry(300, 300, 300, 150) self.setWindowTitle('Adquisición de datos de Motor DC') self.setWindowIcon(QtGui.QIcon('./pictures/logo.png')) try: QtGui.QApplication.setStyle(QtGui.QStyleFactory.create( sys.argv[1])) except: QtGui.QApplication.setStyle( QtGui.QStyleFactory.create('Cleanlooks')) self.show() def closeApplication(self): choice = QtGui.QMessageBox.question( self, 'Leaving so soon?', 'Are you sure you want to exit the program?', QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if choice == QtGui.QMessageBox.Yes: self.miTarjetaAdquisicion.salir() sys.exit() else: pass def intentoIntroducirPuerto(self): exitoConexion = self.miTarjetaAdquisicion.iniciarPuerto( puerto='/dev/' + self.miIntroduccionPuerto.text()) if exitoConexion: self.miEtiquetaPuerto.setText('Exito, conectado a ' + self.miIntroduccionPuerto.text()) self.miIntroduccionPuerto.clear() #setVisible(False) self.botonDeInicio.setEnabled(True) else: self.miEtiquetaPuerto.setText('Aun no puedo conectarme a ' + self.miIntroduccionPuerto.text()) self.miIntroduccionPuerto.clear() def actualizarIngresoDatos(self): campos = [ self.miDataMotor.text(), self.miDatoPotenciaPlaca.text(), self.miDataTensionNominal.text(), self.miDataVelocidadNominal.text(), self.miComentario.toPlainText() ] if (self.miTarjetaAdquisicion.actualizarCampos(campos)): self.botonParaPDF.setEnabled(True) self.botonDeInicializacion.setEnabled(True) else: self.botonParaPDF.setEnabled(False) self.botonDeInicializacion.setEnabled(False) def actualizarOrdenada(self, text): self.refrescarGrafica(self.seleccionDeOrdenada.currentText(), self.seleccionDeAbsisa.currentText(), self.miTarjetaAdquisicion.obtenerUltimosDatos()) def actualizarAbsisa(self, text): self.refrescarGrafica(self.seleccionDeOrdenada.currentText(), self.seleccionDeAbsisa.currentText(), self.miTarjetaAdquisicion.obtenerUltimosDatos()) def importarDatos(self): self.estadoAuxiliar = True self.miTarjetaAdquisicion.recibirInformacion() self.miTituloControlGrafica.setText( 'Graficar : Inicio (' + self.miTarjetaAdquisicion.horaInicioLiteral + ')') self.botonDeCancel.setEnabled(True) self.botonDeInicio.setEnabled(False) self.miTareaGraficaParalela = threading.Thread( target=self.actualizacionAutomaticaGrafica, args=("task", )) self.miTareaGraficaParalela.start() def inicializarTodo(self): # Se hace un refresco previo para borrar los valores que puedan estar en etapa intermedia self.refrescarGrafica('Todos', 'Tiempo', self.miTarjetaAdquisicion.actualizarDatos()) self.miTarjetaAdquisicion.inicializar() self.refrescarGrafica('Todos', 'Tiempo', self.miTarjetaAdquisicion.actualizarDatos()) self.actualizarIngresoDatos() self.botonDeInicio.setEnabled(True) def exportarInformacion(self): self.actualizarIngresoDatos() self.miTarjetaAdquisicion.exportarDatosACSV() self.refrescarGrafica(self.seleccionDeOrdenada.currentText(), self.seleccionDeAbsisa.currentText(), self.miTarjetaAdquisicion.obtenerUltimosDatos(), True) def detenerDatos(self): self.estadoAuxiliar = False self.miTarjetaAdquisicion.detenerInformacion() self.botonDeInicio.setText("Importar Datos") self.botonDeCancel.setEnabled(False) self.miTareaGraficaParalela.do_run = False self.miTareaGraficaParalela.join() self.actualizarIngresoDatos() def actualizacionAutomaticaGrafica(self, argumento): self.miTareaGraficaParalela = threading.currentThread() while getattr(self.miTareaGraficaParalela, "do_run", True): self.refrescarGrafica(self.seleccionDeOrdenada.currentText(), self.seleccionDeAbsisa.currentText(), self.miTarjetaAdquisicion.actualizarDatos()) #print(len(self.miTarjetaAdquisicion.actualizarDatos()[0])) #print('Finalizando grafica desde adentro') def refrescarGrafica(self, argumentoOrdenada, argumentoAbsisa, listaDatos, guardarEnPDF=False): if listaDatos == None: #print('Nada que actualizar') pass else: self.titulo = self.miDataMotor.text() if argumentoOrdenada == 'Todos': graficaActual.cla() ax1 = self.figure.add_subplot(111) t = listaDatos[0] #range(len(listaDatos[0])) v = listaDatos[1] c = listaDatos[2] T = listaDatos[3] r = listaDatos[4] graficaActual.title(self.titulo) graficaActual.ylabel('$[V] [A] [C] [rpm]$') graficaActual.xlabel( self.miTarjetaAdquisicion.horaInicioLiteral + '+ $t [s]$') graficaActual.grid() graficaActual.plot(t, v, label='v') graficaActual.plot(t, c, label='i') graficaActual.plot(t, T, label='T') graficaActual.plot(t, r, label='rpm') #graficaActual.plot(t,v,'b.-',label='v',t,c,'y.-',label='i',t,T,'r.-',label='T',t,r,'g.-',label='rpm') graficaActual.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=4, fancybox=True, shadow=True) if guardarEnPDF: graficaActual.savefig(self.titulo + '_' + self.miTarjetaAdquisicion.fechaHora + '.pdf', bbox_inches='tight') self.canvas.draw() graficaActual.gcf().clear() else: graficaActual.cla() ax1 = self.figure.add_subplot(111) a = listaDatos[self.indices[argumentoAbsisa][0]] o = listaDatos[self.indices[argumentoOrdenada][0]] self.titulo += '_' + argumentoOrdenada + '_vs_' + argumentoAbsisa graficaActual.title(self.titulo) if self.indices[argumentoAbsisa][0] == 0: graficaActual.xlabel( self.miTarjetaAdquisicion.horaInicioLiteral + ' + ' + self.indices[argumentoAbsisa][1]) else: graficaActual.xlabel(self.indices[argumentoAbsisa][1]) graficaActual.ylabel(self.indices[argumentoOrdenada][1]) graficaActual.grid() graficaActual.plot(a, o) if guardarEnPDF: graficaActual.savefig(self.titulo + '_' + self.miTarjetaAdquisicion.fechaHora + '.pdf', bbox_inches='tight') self.canvas.draw()
class SignalViewerWidget(QtGui.QWidget): """Shows different visualizations of a seismic signal (magnitude, envelope, spectrogram, characteristic function). Allows the user to manipulate it (navigate through it, zoom in/out, edit detected events, select threshold value, etc...) """ CF_loaded = QtCore.Signal(bool) event_selected = QtCore.Signal(rc.ApasvoEvent) def __init__(self, parent, document=None): super(SignalViewerWidget, self).__init__(parent) self.document = document self.xmin = 0.0 self.xmax = 0.0 self.xleft = 0.0 self.xright = 0.0 self.time = np.array([]) self.fs = 0.0 self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.fig, _ = plt.subplots(3, 1) self.signal_ax = self.fig.axes[0] self.cf_ax = self.fig.axes[1] self.specgram_ax = self.fig.axes[2] self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding, QtGui.QSizePolicy.Policy.Expanding)) self.canvas.setMinimumHeight(320) self.graphArea = QtGui.QScrollArea(self) self.graphArea.setWidget(self.canvas) self.graphArea.setWidgetResizable(True) self.eventMarkers = {} self.last_right_clicked_event = None self.thresholdMarker = None self.playback_marker = None self.selector = SpanSelector(self.fig) self.minimap = MiniMap(self, self.signal_ax, None) # Load Spectrogram settings self.update_specgram_settings() # Animation related attributes self.background = None self.animated = False # Create context menus self.event_context_menu = QtGui.QMenu(self) self.takanami_on_event_action = QtGui.QAction("Apply Takanami to Event", self) self.takanami_on_event_action.setStatusTip("Refine event position by using Takanami algorithm") self.event_context_menu.addAction(self.takanami_on_event_action) self.takanami_on_event_action.triggered.connect(self.apply_takanami_to_selected_event) self.selection_context_menu = QtGui.QMenu(self) self.create_event_action = QtGui.QAction("Create New Event on Selection", self) self.create_event_action.setStatusTip("Create a new event on selection") self.takanami_on_selection_action = QtGui.QAction("Apply Takanami to Selection", self) self.takanami_on_selection_action.setStatusTip("Apply Takanami algorithm to selection") self.selection_context_menu.addAction(self.create_event_action) self.selection_context_menu.addAction(self.takanami_on_selection_action) self.create_event_action.triggered.connect(self.create_event_on_selection) self.takanami_on_selection_action.triggered.connect(self.apply_takanami_to_selection) # format axes formatter = FuncFormatter(lambda x, pos: clt.float_secs_2_string_date(x, self.document.record.starttime)) for ax in self.fig.axes: ax.callbacks.connect('xlim_changed', self.on_xlim_change) ax.xaxis.set_major_formatter(formatter) plt.setp(ax.get_xticklabels(), visible=True) ax.grid(True, which='both') self.specgram_ax.callbacks.connect('ylim_changed', self.on_ylim_change) self.specgram_ax.set_xlabel('Time (seconds)') plt.setp(self.signal_ax.get_yticklabels(), visible=False) #self.signal_ax.set_ylabel('Signal Amp.') self.cf_ax.set_ylabel('CF Amp.') self.specgram_ax.set_ylabel('Frequency (Hz)') # Set the layout self.layout = QtGui.QVBoxLayout(self) self.layout.addWidget(self.graphArea) self.layout.addWidget(self.minimap) self.selector.toggled.connect(self.minimap.set_selection_visible) self.selector.valueChanged.connect(self.minimap.set_selection_limits) self.selector.right_clicked.connect(self.on_selector_right_clicked) if self.document is not None: self.set_record(document) @property def data_loaded(self): return self.document is not None def set_record(self, document, step=120.0): self.document = document self.fs = self.document.record.fs self.signal = self.document.record.signal self.envelope = env.envelope(self.signal) self.cf = self.document.record.cf self.time = np.linspace(0, len(self.signal) / self.fs, num=len(self.signal), endpoint=False) self.xmax = self.time[-1] # Draw minimap self.minimap.minimapSelector.set(visible=False) # Hide minimap selector while loading self.minimap.set_record(self.document.record, step) # Plot signal step_samples = step * self.fs self._signal_data = self.signal_ax.plot(self.time[:step_samples], self.signal[:step_samples], color='black', rasterized=True)[0] # Plot envelope self._envelope_data = self.signal_ax.plot(self.time[:step_samples], self.envelope[:step_samples], color='red', rasterized=True)[0] # Adjust y axis for signal plot signal_yaxis_max_value = max(np.max(self.signal), np.max(self.envelope)) signal_yaxis_min_value = np.min(self.signal) plotting.adjust_axes_height(self.signal_ax, max_value=signal_yaxis_max_value, min_value=signal_yaxis_min_value) # Plot CF cf_loaded = (self.cf.size != 0) self.set_cf_visible(cf_loaded) self.CF_loaded.emit(cf_loaded) cf_step_samples = min(step_samples,len(self.cf)) self._cf_data = self.cf_ax.plot(self.time[:cf_step_samples], self.cf[:cf_step_samples], color='black', rasterized=True)[0] # Adjust y axis for CF plot if cf_loaded: plotting.adjust_axes_height(self.cf_ax, max_value=np.max(self.cf), min_value=np.min(self.cf)) self.thresholdMarker = ThresholdMarker(self.cf_ax) # Plot espectrogram plotting.plot_specgram(self.specgram_ax, self.signal, self.fs, nfft=self.specgram_windowlen, noverlap=self.specgram_noverlap, window=self.specgram_window) # Set the span selector self.selector.fs = self.fs self.selector.set_active(False) self.selector.set_selection_limits(self.xmin, self.xmax) # Set the playback marker self.playback_marker = PlayBackMarker(self.fig, self) # Set the initial xlimits self.set_xlim(0, step) self.subplots_adjust() # Set event markers self.eventMarkers = {} for event in self.document.record.events: self.create_event(event) # Now activate selector again on minimap self.minimap.minimapSelector.set(visible=True) self.minimap.draw() def unset_record(self): self.document = None self.signal = None self.envelope = None self.cf = None self.time = None self._signal_data = None self._envelope_data = None self._cf_data = None self.xmin, self.xmax = 0.0, 0.0 self.eventMarkers = {} # Clear axes self.signal_ax.lines = [] self.cf_ax.lines = [] self.specgram_ax.lines = [] self.specgram_ax.images = [] self.CF_loaded.emit(False) def update_cf(self): if self.data_loaded: self.cf = self.document.record.cf self._cf_data.set_xdata(self.time[:len(self.cf)]) self._cf_data.set_ydata(self.cf) plotting.adjust_axes_height(self.cf_ax) cf_loaded = (self.cf.size != 0) self.CF_loaded.emit(cf_loaded) self.set_cf_visible(cf_loaded) self.draw() def create_events(self, new_events_set): for event in new_events_set.get(self.document.record.uuid, []): self.create_event(event) def create_event(self, event): event_id = event.resource_id.uuid if event_id not in self.eventMarkers: marker = EventMarker(self.fig, self.minimap, self.document, event) self.eventMarkers[event_id] = marker marker.event_selected.connect(self.event_selected.emit) marker.right_clicked.connect(self.on_event_right_clicked) def delete_events(self, new_events_set): for event in new_events_set.get(self.document.record.uuid, []): self.delete_event(event) def delete_event(self, event): event_id = event.resource_id.uuid self.eventMarkers[event_id].remove() self.eventMarkers.pop(event_id) def update_event(self, event): self.eventMarkers[event.resource_id.uuid].update() def set_xlim(self, l, r): xmin = max(0, l) xmax = min(self.xmax, r) self.signal_ax.set_xlim(xmin, xmax) def on_xlim_change(self, ax): xmin, xmax = ax.get_xlim() if (self.xleft, self.xright) != (xmin, xmax): self.xleft, self.xright = xmin, xmax if self.xmin <= xmin <= xmax <= self.xmax: # Update minimap selector if (xmin, xmax) != self.minimap.get_selector_limits(): self.minimap.set_selector_limits(xmin, xmax) # Update axes for axes in self.fig.axes: if ax != axes: axes.set_xlim(xmin, xmax) # Update data xmin = int(max(0, xmin) * self.fs) xmax = int(min(self.xmax, xmax) * self.fs) pixel_width = np.ceil(self.fig.get_figwidth() * self.fig.get_dpi()) if self._signal_data is not None: x_data, y_data = plotting.reduce_data(self.time, self.signal, pixel_width, xmin, xmax) self._signal_data.set_xdata(x_data) self._signal_data.set_ydata(y_data) if self._envelope_data is not None: x_data, y_data = plotting.reduce_data(self.time, self.envelope, pixel_width, xmin, xmax) self._envelope_data.set_xdata(x_data) self._envelope_data.set_ydata(y_data) if self._cf_data is not None and self.cf_ax.get_visible(): x_data, y_data = plotting.reduce_data(self.time[:len(self.cf)], self.cf, pixel_width, xmin, xmax) self._cf_data.set_xdata(x_data) self._cf_data.set_ydata(y_data) # Draw graph self.draw() else: xmin = max(self.xmin, xmin) xmax = min(self.xmax, xmax) ax.set_xlim(xmin, xmax) def on_ylim_change(self, ax): if self.data_loaded: if ax == self.specgram_ax: ymin, ymax = ax.get_ylim() nyquist_freq = (self.fs / 2.0) if ymin < 0.0: ax.set_ylim(0.0, ymax) elif ymax > nyquist_freq: ax.set_ylim(ymin, nyquist_freq) def set_event_selection(self, events): event_id_list = [event.resource_id.uuid for event in events] for event_id in self.eventMarkers: self.eventMarkers[event_id].set_selected(event_id in event_id_list) self.draw() self.minimap.draw() def set_position(self, pos): """""" xmin, xmax = self.signal_ax.get_xlim() mrange = xmax - xmin l, r = pos - mrange / 2.0, pos + mrange / 2.0 if l < self.xmin: l, r = self.xmin, mrange elif r > self.xmax: l, r = self.xmax - mrange, self.xmax self.set_xlim(l, r) def goto_event(self, event): if event.resource_id.uuid in self.eventMarkers: self.set_position(event.stime / self.fs) def showEvent(self, event): self.draw() self.minimap.draw_animate() def resizeEvent(self, event): self.draw() self.minimap.draw_animate() def set_signal_amplitude_visible(self, show_sa): if self._signal_data is not None and self._envelope_data is not None: if self._signal_data.get_visible() != show_sa: self._signal_data.set_visible(show_sa) show_axis = (self._signal_data.get_visible() + self._envelope_data.get_visible()) self.signal_ax.set_visible(show_axis) if self.data_loaded: self.subplots_adjust() self.draw() def set_signal_envelope_visible(self, show_se): if self._signal_data is not None and self._envelope_data is not None: if self._envelope_data.get_visible() != show_se: self._envelope_data.set_visible(show_se) show_axis = (self._signal_data.get_visible() + self._envelope_data.get_visible()) self.signal_ax.set_visible(show_axis) if self.data_loaded: self.subplots_adjust() self.draw() def set_cf_visible(self, show_cf): if self.cf_ax.get_visible() != show_cf: if self.data_loaded: if len(self.cf) <= 0: self.cf_ax.set_visible(False) else: self.cf_ax.set_visible(show_cf) self.subplots_adjust() self.draw() def set_espectrogram_visible(self, show_eg): if self.specgram_ax.get_visible() != show_eg: self.specgram_ax.set_visible(show_eg) if self.data_loaded: self.subplots_adjust() self.draw() def set_minimap_visible(self, show_mm): if self.minimap.get_visible() != show_mm: self.minimap.set_visible(show_mm) self.minimap.draw_animate() def set_threshold_visible(self, show_thr): if self.thresholdMarker: if self.thresholdMarker.get_visible() != show_thr: self.thresholdMarker.set_visible(show_thr) self.draw() def subplots_adjust(self): visible_subplots = [ax for ax in self.fig.get_axes() if ax.get_visible()] for i, ax in enumerate(visible_subplots): correct_geometry = (len(visible_subplots), 1, i + 1) if correct_geometry != ax.get_geometry(): ax.change_geometry(len(visible_subplots), 1, i + 1) # Adjust space between subplots self.fig.subplots_adjust(left=0.06, right=0.95, bottom=0.14, top=0.95, hspace=0.22) def get_selector_limits(self): return self.selector.get_selector_limits() def set_selector_limits(self, xleft, xright): self.selector.set_selector_limits(xleft, xright) def set_selection_enabled(self, value): self.selector.set_enabled(value) def set_playback_position(self, position): if self.playback_marker is not None: self.playback_marker.set_position(position) self.minimap.playback_marker.set_position(position) def set_playback_marker_visible(self, show_marker): if self.playback_marker is not None: self.playback_marker.set_visible(show_marker) self.minimap.playback_marker.set_visible(show_marker) def on_event_right_clicked(self, event): self.last_right_clicked_event = event self.event_context_menu.exec_(QtGui.QCursor.pos()) def apply_takanami_to_selected_event(self): takanamidialog.TakanamiDialog(self.document, seismic_event=self.last_right_clicked_event).exec_() def apply_takanami_to_selection(self): xleft, xright = self.get_selector_limits() takanamidialog.TakanamiDialog(self.document, xleft, xright).exec_() def create_event_on_selection(self): xleft, xright = self.get_selector_limits() xleft, xright = xleft * self.fs, xright * self.fs cf = self.cf[xleft:xright] if cf.size > 0: time = (xleft + np.argmax(cf)) else: time = (xleft + ((xright - xleft) / 2.0)) self.document.createEvent(time=time) def draw(self): if self.animated: self._draw_animate() else: self.canvas.draw_idle() def _draw_animate(self): self.canvas.restore_region(self.background) for artist in self._get_animated_artists(): if artist.get_visible(): ax = artist.get_axes() if ax is not None: if artist.get_axes().get_visible(): self.fig.draw_artist(artist) else: self.fig.draw_artist(artist) self.canvas.blit(self.fig.bbox) def _set_animated(self, value): if self.animated != value: self.animated = value for artist in self._get_animated_artists(): artist.set_animated(value) if self.animated == True: images = [] for ax in self.fig.axes: images.extend(ax.images) for image in images: image.set_visible(False) self.canvas.draw() self.background = self.canvas.copy_from_bbox(self.fig.bbox) for image in images: image.set_visible(True) def _get_animated_artists(self): artists = [] for ax in self.fig.axes: artists.extend(ax.images) artists.extend(ax.lines) artists.append(ax.xaxis) artists.append(ax.yaxis) artists.extend(ax.patches) artists.extend(ax.spines.values()) for artist in artists: yield artist def update_specgram_settings(self): # load specgram settings settings = QtCore.QSettings(_organization, _application_name) settings.beginGroup("specgram_settings") self.specgram_windowlen = int(settings.value('window_len', settingsdialog.SPECGRAM_WINDOW_LENGTHS[4])) self.specgram_noverlap = int(settings.value('noverlap', self.specgram_windowlen / 2)) self.specgram_window = settings.value('window', plotting.SPECGRAM_WINDOWS[2]) settings.endGroup() if self.data_loaded: # Plot espectrogram self.specgram_ax.images = [] # Save x-axis limits limits = self.signal_ax.get_xlim() # Draw spectrogram plotting.plot_specgram(self.specgram_ax, self.signal, self.fs, nfft=self.specgram_windowlen, noverlap=self.specgram_noverlap, window=self.specgram_window) # Restore x-axis limits self.signal_ax.set_xlim(*limits) def paintEvent(self, paintEvent): super(SignalViewerWidget, self).paintEvent(paintEvent) def on_selector_right_clicked(self): xleft, xright = self.get_selector_limits() self.takanami_on_selection_action.setEnabled((xright - xleft) >= (takanamidialog.MINIMUM_MARGIN_IN_SECS * 2)) self.selection_context_menu.exec_(QtGui.QCursor.pos())