class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None): QtGui.QWidget.__init__(self, parent) self.canvas = MyMplCanvas() #self.toolbar = MyNavigationToolbar(self.canvas, self.canvas, direction = 'v') self.toolbar = NavigationToolbar(self.canvas, self.canvas) #self.toolbar.hide() self.hbox = QtGui.QHBoxLayout() #self.hbox.addWidget(self.toolbar) self.hbox.addWidget(self.canvas) self.setLayout(self.hbox) ########################## self.hZoom = QtGui.QAction("Zoom", self) self.hZoom.setShortcut("Ctrl+Z") self.addAction(self.hZoom) QtCore.QObject.connect(self.hZoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) def ZoomToggle(self): self.toolbar.zoom() def autoscale_plot(self): self.toolbar.home()
class MPL_Widget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.canvas = MyMplCanvas() #self.toolbar = MyNavigationToolbar(self.canvas, self.canvas, direction = 'v') self.toolbar = NavigationToolbar(self.canvas, self.canvas) #self.toolbar.hide() self.hbox = QtGui.QHBoxLayout() #self.hbox.addWidget(self.toolbar) self.hbox.addWidget(self.canvas) self.setLayout(self.hbox) ########################## self.hZoom = QtGui.QAction("Zoom", self) self.hZoom.setShortcut("Ctrl+Z") self.addAction(self.hZoom) QtCore.QObject.connect(self.hZoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.actionAutoScale = QtGui.QAction("AutoScale", self) #self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) def ZoomToggle(self): self.toolbar.zoom() def autoscale_plot(self): self.toolbar.home()
class MPL_Widget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.canvas = MyMplCanvas() #self.toolbar = MyNavigationToolbar(self.canvas, self.canvas, direction = 'v') self.toolbar = NavigationToolbar(self.canvas, self.canvas) self.toolbar.hide() self.hbox = QtGui.QHBoxLayout() #self.hbox.addWidget(self.toolbar) self.hbox.addWidget(self.canvas) self.setLayout(self.hbox) ########################## self.hZoom = QtGui.QAction("Zoom", self) self.hZoom.setShortcut("Ctrl+Z") self.addAction(self.hZoom) QtCore.QObject.connect(self.hZoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.actionAutoScale = QtGui.QAction("AutoScale", self) #self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.installEventFilter(EventFilter(self)) ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath, 'tempMPL.png') def ZoomToggle(self): self.toolbar.zoom() def autoscale_plot(self): self.toolbar.home() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n" % (sys.exc_type, sys.exc_value) print errorMsg def focusEvent(self, event): # self.enableAutoScale() # self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): # self.disableAutoScale() # self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction)
def zoom(self, *args): NavigationToolbar2QT.zoom(self, *args) self.activate_widget('zoom', not self.isZoomActivated)
class StartQt4(QMainWindow): def __init__(self,parent=None): QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.atten = -1 self.ui.atten.setValue(self.atten) self.resnum = 0 self.indx=0 QObject.connect(self.ui.open_browse, SIGNAL("clicked()"), self.open_dialog) QObject.connect(self.ui.save_browse, SIGNAL("clicked()"), self.save_dialog) QObject.connect(self.ui.atten, SIGNAL("valueChanged(int)"), self.setnewatten) QObject.connect(self.ui.savevalues, SIGNAL("clicked()"), self.savevalues) QObject.connect(self.ui.jumptores, SIGNAL("clicked()"), self.jumptores) self.widesweep=None try: path='/home/data/MEC/20180517/' ws_FN = 'HypatiaFL5a_digWS_r222.txt' ws_freqs_all_FN = 'HypatiaFL5a_digWS_r222-freqs-all.txt' ws_freqs_good_FN = 'HypatiaFL5a_digWS_r222-freqs-good.txt' self.widesweep=numpy.loadtxt(path+ws_FN) #freq, I, Q self.widesweep_goodFreqs = numpy.loadtxt(path+ws_freqs_good_FN ,usecols=[2]) self.widesweep_allResIDs,self.widesweep_allFreqs = numpy.loadtxt(path+ws_freqs_all_FN,usecols=[0,2],unpack=True) except IOError: pass self.navi_toolbar = NavigationToolbar(self.ui.plot_3.canvas, self) self.ui.plot_3.canvas.setFocusPolicy( Qt.ClickFocus ) cid=self.ui.plot_3.canvas.mpl_connect('key_press_event', self.zoom_plot_3) def open_dialog(self): self.openfile = QFileDialog.getOpenFileName(parent=None, caption=QString(str("Choose PS File")),directory = ".",filter=QString(str("H5 (*.h5)"))) self.ui.open_filename.setText(str(self.openfile)) self.loadps() def save_dialog(self): self.savefile = QFileDialog.getOpenFileName(parent=None, caption=QString(str("Choose Save File")),directory = ".") self.ui.save_filename.setText(str(self.savefile)) self.f = open(str(self.savefile), 'a') self.f.close() self.mlResIDs, self.mlFreqs, self.mlAttens = np.loadtxt(str(self.savefile), unpack=True) def loadres(self): self.Res1=IQsweep() self.Res1.LoadPowers(str(self.openfile), 'r0', self.freq[self.resnum]) self.ui.res_num.setText(str(self.resnum)) self.resfreq = self.freq[self.resnum] self.resID =self.Res1.resID print "Res: "+str(self.resnum)+' --> ID: '+str(self.resID) self.ui.frequency.setText(str(self.resfreq)) self.NAttens = len(self.Res1.atten1s) self.res1_iq_vels=numpy.zeros((self.NAttens,self.Res1.fsteps-1)) self.res1_iq_amps=numpy.zeros((self.NAttens,self.Res1.fsteps)) for iAtt in range(self.NAttens): for i in range(1,self.Res1.fsteps-1): self.res1_iq_vels[iAtt,i]=sqrt((self.Res1.Qs[iAtt][i]-self.Res1.Qs[iAtt][i-1])**2+(self.Res1.Is[iAtt][i]-self.Res1.Is[iAtt][i-1])**2) self.res1_iq_amps[iAtt,:]=sqrt((self.Res1.Qs[iAtt])**2+(self.Res1.Is[iAtt])**2) #Sort the IQ velocities for each attenuation, to pick out the maximums sorted_vels = numpy.sort(self.res1_iq_vels,axis=1) #Last column is maximum values for each atten (row) self.res1_max_vels = sorted_vels[:,-1] #Second to last column has second highest value self.res1_max2_vels = sorted_vels[:,-2] #Also get indices for maximum of each atten, and second highest sort_indices = numpy.argsort(self.res1_iq_vels,axis=1) max_indices = sort_indices[:,-1] max2_indices = sort_indices[:,-2] max_neighbor = max_indices.copy() #for each attenuation find the ratio of the maximum velocity to the second highest velocity self.res1_max_ratio = self.res1_max_vels.copy() max_neighbors = zeros(self.NAttens) max2_neighbors = zeros(self.NAttens) self.res1_max2_ratio = self.res1_max2_vels.copy() for iAtt in range(self.NAttens): if max_indices[iAtt] == 0: max_neighbor = self.res1_iq_vels[iAtt,max_indices[iAtt]+1] elif max_indices[iAtt] == len(self.res1_iq_vels[iAtt,:])-1: max_neighbor = self.res1_iq_vels[iAtt,max_indices[iAtt]-1] else: max_neighbor = maximum(self.res1_iq_vels[iAtt,max_indices[iAtt]-1],self.res1_iq_vels[iAtt,max_indices[iAtt]+1]) max_neighbors[iAtt]=max_neighbor self.res1_max_ratio[iAtt] = self.res1_max_vels[iAtt]/max_neighbor if max2_indices[iAtt] == 0: max2_neighbor = self.res1_iq_vels[iAtt,max2_indices[iAtt]+1] elif max2_indices[iAtt] == len(self.res1_iq_vels[iAtt,:])-1: max2_neighbor = self.res1_iq_vels[iAtt,max2_indices[iAtt]-1] else: max2_neighbor = maximum(self.res1_iq_vels[iAtt,max2_indices[iAtt]-1],self.res1_iq_vels[iAtt,max2_indices[iAtt]+1]) max2_neighbors[iAtt]=max2_neighbor self.res1_max2_ratio[iAtt] = self.res1_max2_vels[iAtt]/max2_neighbor #normalize the new arrays self.res1_max_vels /= numpy.max(self.res1_max_vels) self.res1_max_vels *= numpy.max(self.res1_max_ratio) self.res1_max2_vels /= numpy.max(self.res1_max2_vels) #self.res1_relative_max_vels /= numpy.max(self.res1_relative_max_vels) self.ui.plot_1.canvas.ax.clear() print 'file', self.openfile print 'attens', self.Res1.atten1s self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,self.res1_max_vels,'b.-',label='Max IQ velocity') #self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,max_neighbors,'r.-') self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,self.res1_max_ratio,'k.-',label='Ratio (Max Vel)/(2nd Max Vel)') self.ui.plot_1.canvas.ax.legend() self.ui.plot_1.canvas.ax.set_xlabel('attenuation') #self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,self.res1_max2_vels-1,'b.-') #self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,max2_neighbors-1,'b.-') #self.ui.plot_1.canvas.ax.plot(self.Res1.atten1s,self.res1_max2_ratio-1,'g.-') # Chris S: seems that button_press_event causes click_plot_1 to be called more than once sometimes. cid=self.ui.plot_1.canvas.mpl_connect('button_press_event', self.click_plot_1) #cid=self.ui.plot_1.canvas.mpl_connect('button_release_event', self.click_plot_1) #self.ui.plot_1.canvas.format_labels() self.ui.plot_1.canvas.draw() max_ratio_threshold = 1.5 rule_of_thumb_offset = 2 # require ROTO adjacent elements to be all below the MRT bool_remove = np.ones(len(self.res1_max_ratio)) for ri in range(len(self.res1_max_ratio)-rule_of_thumb_offset-2): bool_remove[ri] = bool((self.res1_max_ratio[ri:ri+rule_of_thumb_offset+1]< max_ratio_threshold).all()) if(np.any(self.resID==self.mlResIDs)): resInd = np.where(self.resID==self.mlResIDs)[0] self.select_atten(self.mlAttens[resInd]) self.ui.atten.setValue(self.mlAttens[resInd]) else: guess_atten_idx = np.extract(bool_remove,np.arange(len(self.res1_max_ratio))) # require the attenuation value to be past the initial peak in MRT guess_atten_idx = guess_atten_idx[where(guess_atten_idx > argmax(self.res1_max_ratio) )[0]] if size(guess_atten_idx) >= 1: if guess_atten_idx[0]+rule_of_thumb_offset < len(self.Res1.atten1s): guess_atten_idx[0] += rule_of_thumb_offset guess_atten = self.Res1.atten1s[guess_atten_idx[0]] self.select_atten(guess_atten) self.ui.atten.setValue(round(guess_atten)) else: self.select_atten(self.Res1.atten1s[self.NAttens/2]) self.ui.atten.setValue(round(self.Res1.atten1s[self.NAttens/2])) def guess_res_freq(self): if(np.any(self.resID==self.mlResIDs)): resInd = np.where(self.resID==self.mlResIDs)[0] self.select_freq(self.mlFreqs[resInd]) else: guess_idx = argmax(self.res1_iq_vels[self.iAtten]) #The longest edge is identified, choose which vertex of the edge #is the resonant frequency by checking the neighboring edges #len(IQ_vels[ch]) == len(f_span)-1, so guess_idx is the index #of the lower frequency vertex of the longest edge if guess_idx-1 < 0 or self.res1_iq_vel[guess_idx-1] < self.res1_iq_vel[guess_idx+1]: iNewResFreq = guess_idx else: iNewResFreq = guess_idx-1 guess = self.Res1.freq[iNewResFreq] print 'Guessing resonant freq at ',guess,' for self.iAtten=',self.iAtten self.select_freq(guess) def loadps(self): #### IN HERE NEED TO ADD LOADING OF ID FIELD FROM PS hd5file=open_file(str(self.openfile),mode='r') group = hd5file.get_node('/','r0') self.freq=empty(0,dtype='float32') self.idList=empty(0,dtype='int32') for sweep in group._f_walknodes('Leaf'): k=sweep.read() self.scale = k['scale'][0] #print "Scale factor is ", self.scale self.freq=append(self.freq,[k['f0'][0]]) self.idList=append(self.idList,[k['resID'][0]]) #self.freqList = np.zeros(len(k['f0'])) #self.attenList = np.zeros(len(self.freqList)) - 1 self.freqList = np.zeros(2000) #self.idList = np.zeros(len(self.freqList)) - 1 self.attenList = np.zeros(len(self.freqList)) - 1 hd5file.close() self.loadres() def on_press(self, event): self.select_freq(event.xdata) def zoom_plot_3(self,event): if str(event.key) == str('z'): print 'zoooom' self.navi_toolbar.zoom() def click_plot_1(self, event): #Chris. self.select_atten(event.xdata) self.ui.atten.setValue(round(event.xdata)) def select_freq(self,freq): self.resfreq = freq self.ui.frequency.setText(str(self.resfreq)) self.ui.plot_2.canvas.ax.plot(self.Res1.freq[self.indx],self.res1_iq_vel[self.indx],'bo') self.ui.plot_3.canvas.ax.plot(self.Res1.I[self.indx],self.Res1.Q[self.indx],'bo') self.indx=where(self.Res1.freq >= self.resfreq)[0][0] self.ui.plot_2.canvas.ax.plot(self.Res1.freq[self.indx],self.res1_iq_vel[self.indx],'ro') self.ui.plot_2.canvas.draw() self.ui.plot_3.canvas.ax.plot(self.Res1.I[self.indx],self.Res1.Q[self.indx],'ro') self.ui.plot_3.canvas.draw() def select_atten(self,attenuation): if self.atten != -1: attenIndex = where(self.Res1.atten1s == self.atten) if size(attenIndex) >= 1: self.iAtten = attenIndex[0][0] self.ui.plot_1.canvas.ax.plot(self.atten,self.res1_max_ratio[self.iAtten],'ko') self.ui.plot_1.canvas.ax.plot(self.atten,self.res1_max_vels[self.iAtten],'bo') self.atten = round(attenuation) attenIndex = where(self.Res1.atten1s == self.atten) if size(attenIndex) != 1: print "Atten value is not in file" return self.iAtten = attenIndex[0][0] self.res1_iq_vel = self.res1_iq_vels[self.iAtten,:] self.Res1.I=self.Res1.Is[self.iAtten] self.Res1.Q=self.Res1.Qs[self.iAtten] self.Res1.Icen=self.Res1.Icens[self.iAtten] self.Res1.Qcen=self.Res1.Qcens[self.iAtten] self.ui.plot_1.canvas.ax.plot(self.atten,self.res1_max_ratio[self.iAtten],'ro') self.ui.plot_1.canvas.ax.plot(self.atten,self.res1_max_vels[self.iAtten],'ro') self.ui.plot_1.canvas.draw() #Chris S self.ui.atten.setValue(self.atten) self.makeplots() self.guess_res_freq() def makeplots(self): try: #Plot transmission magnitudeds as a function of frequency for this resonator #self.ui.plot_1.canvas.ax.clear() #self.ui.plot_1.canvas.ax.semilogy(self.Res1.freq,res1_iq_amp,'.-') #self.ui.plot_1.canvas.format_labels() #self.ui.plot_1.canvas.draw() self.ui.plot_2.canvas.ax.clear() self.ui.plot_2.canvas.ax.set_xlabel('frequency (GHz)') self.ui.plot_2.canvas.ax.set_ylabel('IQ velocity') self.ui.plot_2.canvas.ax.plot(self.Res1.freq[:-1],self.res1_iq_vel,'b.-') if self.iAtten > 0: self.ui.plot_2.canvas.ax.plot(self.Res1.freq[:-1],self.res1_iq_vels[self.iAtten-1],'g.-') self.ui.plot_2.canvas.ax.lines[-1].set_alpha(.7) if self.iAtten > 1: self.ui.plot_2.canvas.ax.plot(self.Res1.freq[:-1],self.res1_iq_vels[self.iAtten-2],'g.-') self.ui.plot_2.canvas.ax.lines[-1].set_alpha(.3) cid=self.ui.plot_2.canvas.mpl_connect('button_press_event', self.on_press) if self.widesweep is not None: freq_start = self.Res1.freq[0]/1.E9 freq_stop = self.Res1.freq[-1]/1.E9 widesweep_inds = np.where(np.logical_and(self.widesweep[:,0]>=freq_start, self.widesweep[:,0]<=freq_stop)) iqVel_med = numpy.median(self.res1_iq_vel) ws_amp = (self.widesweep[widesweep_inds,1]**2. + self.widesweep[widesweep_inds,2]**2.)**0.5 #ws_amp = 10.*numpy.log10(ws_amp) ws_amp_med = numpy.median(ws_amp) ws_amp*=1.0*iqVel_med/ws_amp_med self.ui.plot_2.canvas.ax.plot(self.widesweep[widesweep_inds,0]*1.E9, ws_amp,'k.-') self.ui.plot_2.canvas.ax.lines[-1].set_alpha(.5) #ws_goodFreqs = self.widesweep_goodFreqs[numpy.where(numpy.logical_and(self.widesweep_goodFreqs>=freq_start,self.widesweep_goodFreqs<=freq_stop))] ws_allFreqs = self.widesweep_allFreqs[numpy.where(numpy.logical_and(self.widesweep_allFreqs>=freq_start,self.widesweep_allFreqs<=freq_stop))] ws_allResIDs = self.widesweep_allResIDs[numpy.where(numpy.logical_and(self.widesweep_allFreqs>=freq_start,self.widesweep_allFreqs<=freq_stop))] for ws_resID_i, ws_freq_i in zip(ws_allResIDs,ws_allFreqs): ws_color = 'k' if ws_freq_i in self.widesweep_goodFreqs: ws_color='r' self.ui.plot_2.canvas.ax.axvline(ws_freq_i*1.E9, c=ws_color, alpha=0.5) ws_ymax=self.ui.plot_2.canvas.ax.yaxis.get_data_interval()[1] self.ui.plot_2.canvas.ax.text(x=ws_freq_i*1.E9, y=ws_ymax,s=str(int(ws_resID_i)), color=ws_color, alpha=0.5) self.ui.plot_2.canvas.draw() self.ui.plot_3.canvas.ax.clear() if self.iAtten >0: self.ui.plot_3.canvas.ax.plot(self.Res1.Is[self.iAtten-1],self.Res1.Qs[self.iAtten-1],'g.-') self.ui.plot_3.canvas.ax.lines[0].set_alpha(.6) if self.iAtten > 1: self.ui.plot_3.canvas.ax.plot(self.Res1.Is[self.iAtten-2],self.Res1.Qs[self.iAtten-2],'g.-') self.ui.plot_3.canvas.ax.lines[-1].set_alpha(.3) self.ui.plot_3.canvas.ax.plot(self.Res1.I,self.Res1.Q,'.-') if self.widesweep is not None: ws_I = self.widesweep[widesweep_inds,1] ws_Q = self.widesweep[widesweep_inds,2] ws_dataRange_I = self.ui.plot_3.canvas.ax.xaxis.get_data_interval() ws_dataRange_Q = self.ui.plot_3.canvas.ax.yaxis.get_data_interval() ws_I -= numpy.median(ws_I) - numpy.median(ws_dataRange_I) ws_Q -= numpy.median(ws_Q) - numpy.median(ws_dataRange_Q) #self.ui.plot_3.canvas.ax.plot(ws_I, ws_Q,'k.-') #self.ui.plot_3.canvas.ax.lines[-1].set_alpha(.5) #self.ui.plot_3.canvas.format_labels() print 'makeplots' self.ui.plot_3.canvas.draw() except IndexError: self.f.close() print "reached end of resonator list, saving file" print "closing GUI" sys.exit() def jumptores(self): try: self.atten = -1 self.resnum = self.ui.jumptonum.value() self.resfreq = self.resnum self.loadres() except IndexError: print "Res value out of bounds." self.ui.plot_1.canvas.ax.clear() self.ui.plot_2.canvas.ax.clear() self.ui.plot_3.canvas.ax.clear() self.ui.plot_1.canvas.draw() self.ui.plot_2.canvas.draw() self.ui.plot_3.canvas.draw() def setnewatten(self): #Chris S.: this is the only place that select_atten should be called. self.select_atten(self.ui.atten.value()) def savevalues(self): #if self.resnum == 0: # self.f = open(str(self.savefile), 'a') # self.f.write(str(self.scale)+'\t'+str(self.scale)+'\t'+str(self.scale)+'\t'+str(self.scale)+'\n') # self.f.close() #Icen=0 #Qcen=0 #self.idList[self.resnum] = self.id assert self.idList[self.resnum]==self.resID, "Something is wrong. Need to debug resID" self.freqList[self.resnum] = self.resfreq self.attenList[self.resnum] = self.atten data = np.transpose([self.idList[np.where(self.attenList >=0)], self.freqList[np.where(self.attenList >=0)], self.attenList[np.where(self.attenList >=0)]]) print data try: #grab and append any data already saved dataCurrent = np.atleast_2d(np.loadtxt(str(self.savefile))) if len(dataCurrent)<1 or len(dataCurrent[0])<1: raise IOError('') # remove duplicates #notDuplicates = np.where(np.in1d(dataCurrent[:,0], data[:,0],invert=True)) # freqs aren't duplicated at these indices #dataCurrent = dataCurrent[notDuplicates,:] #remove doubles based on freq #doubleThreshold = 0.05e6 # 100 kHz #closestIdx = [(np.abs(data[:,1] - i)).argmin() for i in dataCurrent[:,1]] #notDoubles = np.where(np.abs(dataCurrent[:,1] - data[closestIdx,1]) > doubleThreshold)[0] #dataCurrent = dataCurrent[notDoubles,:] #remove doubles based on ID (seems to be bug in code that writes some lines twice) #doubleThreshold = 0.1e6 #closestIdx = [(np.abs(data[:,0] - i)).argmin() for i in dataCurrent[:,0]] #notDoubles = np.where(np.abs(dataCurrent[:,0] - data[closestIdx,0]) > doubleThreshold)[0] #dataCurrent = dataCurrent[notDoubles,:] print dataCurrent dataNew = np.append(dataCurrent,data,axis=0) #sort the frequencies and remove duplicate IDs ids = np.copy(dataNew[:,0][::-1]) freqs = np.copy(dataNew[:,1][::-1]) attens = np.copy(dataNew[:,2][::-1]) newIDs, indx = np.unique(ids, return_index=True) newFreqs = freqs[indx] newAttens = attens[indx] #sort the frequencies #ids = np.copy(dataNew[:,0][::-1]) #freqs = np.copy(dataNew[:,1][::-1]) #attens = np.copy(dataNew[:,2][::-1]) #newFreqs, indx = np.unique(freqs, return_index=True) #newIDs = ids[indx] #newAttens = attens[indx] ''' #Remove any doubles doubleThreshold = 0.5e6 # 500 kHz freqDiff = newFreqs[1:] - newFreqs[:-1] freqDiff = np.append(freqDiff, [doubleThreshold+1]) # last frequency is never a double notDoubles = np.where(freqDiff > doubleThreshold) newFreqs = newFreqs[notDoubles] newAttens = newAttens[notDoubles] ''' data = np.transpose([newIDs,newFreqs,newAttens]) except IOError: print 'IOError' pass np.savetxt(str(self.savefile), data, "%6i %10.9e %4i") #self.f = open(str(self.savefile), 'a') #self.f.write(str(self.resfreq)+'\t'+str(Icen)+'\t'+str(Qcen)+'\t'+str(self.atten)+'\n') #self.f.write(str(self.resfreq)+'\t'+str(self.atten)+'\n') #self.f.close() print " ....... Saved to file: resnum=",self.resnum," resID=",self.resID, " resfreq=",self.resfreq," atten=",self.atten self.resnum += 1 self.atten = -1 self.loadres()
class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None): QtGui.QWidget.__init__(self, parent) self.canvas = MyMplCanvas() #self.toolbar = MyNavigationToolbar(self.canvas, self.canvas, direction = 'v') self.toolbar = NavigationToolbar(self.canvas, self.canvas) self.toolbar.hide() self.hbox = QtGui.QHBoxLayout() #self.hbox.addWidget(self.toolbar) self.hbox.addWidget(self.canvas) self.setLayout(self.hbox) ########################## self.hZoom = QtGui.QAction("Zoom", self) self.hZoom.setShortcut("Ctrl+Z") self.addAction(self.hZoom) QtCore.QObject.connect(self.hZoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.installEventFilter(EventFilter(self)) ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath,'tempMPL.png') def ZoomToggle(self): self.toolbar.zoom() def autoscale_plot(self): self.toolbar.home() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg def focusEvent(self, event): # self.enableAutoScale() # self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): # self.disableAutoScale() # self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction)
class Rt60Widget(QtGui.QWidget): """Widget defined in Qt Designer""" def __init__(self, parent = None): # initialization of Qt MainWindow widget QtGui.QWidget.__init__(self, parent) # set the canvas to the Matplotlib widget self.canvas = Rt60Canvas() # create a vertical box layout self.vbl = QtGui.QVBoxLayout() # add rt60 widget to vertical box self.vbl.addWidget(self.canvas) # add interactive navigation self.navi_toolbar = NavigationToolbar(self.canvas, self) self.vbl.addWidget(self.navi_toolbar) # bind events related to drawing lines self.canvas.mpl_connect('button_press_event', self.on_press) self.canvas.mpl_connect('button_release_event', self.on_release) self.canvas.mpl_connect('motion_notify_event', self.on_motion) # set the layout to th vertical box self.setLayout(self.vbl) # no buttons pressed self.press = None # the line that users get to draw self.linex = [0] self.liney = [0] self.line, = self.canvas.ax.plot(self.linex, self.liney) self.line.set_color("red") self.line.set_linewidth(1.5) self.line.set_linestyle('-') # initialize annotation self.status_text = self.canvas.ax.text(0.45, 0.9, '', transform=self.canvas.ax.transAxes,size=14,ha='center') # self.octave_text = self.canvas.ax.text(0.95, 0.86, '', transform=self.canvas.ax.transAxes,size=14,ha='right') # intialize plot area with some blank data # self.mainplot = self.canvas.ax.plot([0], [0], color="blue") def legend_string(self,instr): instr = "%s" % instr # just to make sure it's of the right 'type' outstr = path.basename(instr) match = re.match(r"(.*)\.wav",outstr) # take out the .wav if possible if (match is not None): outstr = match.group(1) return outstr def refresh(self): # some code taken from init self.canvas.ax.clear() # the line that users get to draw self.line, = self.canvas.ax.plot(self.linex, self.liney) self.line.set_color("red") self.line.set_linewidth(2.0) self.line.set_linestyle('-') ## initialize annotation self.status_text = self.canvas.ax.text(0.45, 0.9, '', transform=self.canvas.ax.transAxes,size=14,ha='center') # self.octave_text = self.canvas.ax.text(0.95, 0.86, '', transform=self.canvas.ax.transAxes,size=14,ha='right') def on_press(self, event): 'on button press we will start drawing a line' #unless we're in pan or zoom interactive mode mode = self.canvas.ax.get_navigate_mode() if ((mode != 'ZOOM') & (mode != 'PAN')): x0, y0 = event.xdata, event.ydata self.press = x0, y0 def on_motion(self, event): 'on motion we will draw the line ' if self.press is None: return x0, y0 = self.press x = x0, event.xdata y = y0, event.ydata # the line that users get to draw #self.line, = self.canvas.ax.plot([0], [0]) #self.line.set_color("red") #self.line.set_linewidth(1.5) #self.line.set_linestyle('-') self.line.set_data(x, y) # this sets up the line to be drawn self.linex = x self.liney = y if (y[1] != y[0]): rt60 = -60.0*(x[1]-x[0])/(1.0*y[1]-y[0]) # print 'RT60(s)= ',rt60 status_template = 'RT60 = %.2f s' self.status_text.set_text(status_template%(rt60)) #octave_template = '%s Octave' #octave_text = str(self.parent.parent.canvas.mplcomboBox.currentText()) #self.octave_text.set_text(octave_template%(octave_text)) self.line.figure.canvas.draw() # update the canvas def on_release(self, event): 'on release we reset the press data' self.press = None mode = self.canvas.ax.get_navigate_mode() # undo any zoom effects if ('ZOOM' == mode): self.navi_toolbar.zoom() return def disconnect(self): 'disconnect all the stored connection ids' self.line.figure.canvas.mpl_disconnect(self.cidpress) self.line.figure.canvas.mpl_disconnect(self.cidrelease) self.line.figure.canvas.mpl_disconnect(self.cidmotion) def update_graph(self,amp,t,filenameA,ampB,tB, filenameB): print "in rt60's update_graph: filenameA = %s" % filenameA """Updates the graph with new data/annotations""" #fig = pl.figure() #ax = fig.add_subplot(111) epsilon = 1.0e-8 # added to avoid log(0) errors # Compute the quantity to be plotted power = (amp + epsilon) **2 maxval = 1.0*np.max(power) power = power / maxval dB = 10*np.ma.log10(np.abs(power)) # "ma"=masked array, throws out -Inf values # Downsample for plotting purposes. (otherwise the plotting takes forever) nsamples = len(dB) if (nsamples > 100000): plotsamples = 2048 elif (nsamples > 50000): plotsamples = 2048 else: plotsamples = 1024 # print "downsampling, original length = ",len(dB) #ds_dB, ds_t = signal.resample(dB,plotsamples,t) ds_dB, ds_t = my_resample(dB,plotsamples,t) #ds_dB, ds_t = dB, t # no sampling # print "finished downsampling" # Set up the plot self.refresh() p1, = self.canvas.ax.plot(ds_t, ds_dB,color="blue",lw=1) leg_fA = self.legend_string(filenameA) # second file if (filenameB is not "") and (ampB is not None) and (len(ampB) > 1): powerB = (ampB+epsilon)**2 powerB = powerB / maxval # use same max value as for file A dB_B = 10*np.ma.log10(np.abs(powerB)) # "ma"=masked array, throws out -Inf values # Downsample for plotting purposes. (otherwise the plotting takes forever) nsamplesB = len(dB_B) if (nsamplesB > 100000): plotsamplesB = 4096 elif (nsamplesB > 50000): plotsamplesB = 2048 else: plotsamplesB = 1024 ds_dB_B,ds_t_B = signal.resample(dB_B,plotsamplesB,tB) p2, = self.canvas.ax.plot(ds_t_B, ds_dB_B,color="purple",lw=1) leg_fB = self.legend_string(filenameB) l1 = self.canvas.ax.legend([p1,p2], [leg_fA,leg_fB], loc=1) else: l1 = self.canvas.ax.legend([p1], [leg_fA], loc=1) l1.draw_frame(False) # no box around the legend self.canvas.ax.grid(True) #draw the line again, on top self.line, = self.canvas.ax.plot(self.linex, self.liney) self.line.set_data(self.linex, self.liney) self.line.set_color("red") self.line.set_linewidth(2.0) self.line.set_linestyle('-') self.line.figure.canvas.draw() # Annotation self.canvas.ax.set_xlabel('Time (s)') self.canvas.ax.set_ylabel('Power (dB) ') # self.canvas.ax.set_title('Click and drag a line using the mouse, to measure RT60') # Actually draw everything self.canvas.draw()
class MPL_Widget(QtGui.QWidget): def __init__(self, parent=None, enableAutoScale=True, enableCSV=False, enableEdit=True, doublePlot=False, layoutDir='h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) # self.toolbar.hide() self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ########################## self.dataLabels = None ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath, 'tempMPL.png') if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False self.x = None #used for picker self.y = None #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### self.clearPlotAction = QtGui.QAction("Clear Plot", self) self.addAction(self.clearPlotAction) QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # def focusOutEvent(self, event): # print "Focus Out" def clearPlot(self): print "Clear Plot" self.canvas.ax.cla() self.canvas.format_labels() self.canvas.draw() # def __initContextMenus__(self): # self.clearPlotAction = QtGui.QAction("Clear Plot", self) # self.addAction(self.clearPlotAction) # QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # # self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.connect(self, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.plotTabContext) # def plotTabContext(self, point): # '''Create a menu for mainTabWidget''' # plotCT_menu = QtGui.QMenu("Menu", self) # plotCT_menu.addAction(self.Zoom) # plotCT_menu.addAction(self.actionAutoScale) # plotCT_menu.addSeparator() # plotCT_menu.addAction(self.clearPlotAction) # plotCT_menu.exec_(self.mapToGlobal(point)) def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction, QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction, QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction, QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self) #self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale, QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction, QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction, QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()] = line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx=curAx, parent=self).exec_(): if self.addLegend: curAx.legend(borderaxespad=0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): self.toolbar.zoom() #this implements the classic zoom # if self.hZoom: # self.hZoom = False # self.span.visible = False # else: # self.hZoom = True # self.span.visible = True def autoscale_plot(self): self.toolbar.home() #implements the classic return to home # self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) # self.canvas.draw() # self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) # def onclick(self, event): # #sets up the maximum Y level to be displayed after the zoom. # #if not set then it maxes to the largest point in the data # #not necessarily the local max # if event.ydata != None: # self.localYMax = int(event.ydata) # # def onselect(self, xmin, xmax): # #print xmin, xmax # if self.hZoom: # self.canvas.ax.set_ylim(ymax = self.localYMax) # self.canvas.ax.set_xlim(xmin, xmax) # self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter=',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter=',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n" % (sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def removePicker(self): try: self.handleA.remove() except: print "" def setData(self, x, y): if x != None: self.x = x if y != None: self.y = y def addPicker(self): '''Sets up the plot variables used for interaction''' self.handleA, = self.canvas.ax.plot([0], [0], 'o',\ ms=8, alpha=.5, color='yellow', visible=True, label = '_nolegend_') self.is_hZoom = False self.canvas.mpl_connect('pick_event', self.OnPickPlot) def OnPickPlot(self, event): self.pickIndex = event.ind[0] try: self.textHandle.remove() except: pass self.curText = event.artist.get_label() if self.x != None and self.y != None: #I'd rather do the following ALWAYS but it seems difficult to do in terms of keeping track of which arrays were plotted when multiple plots are present paramVal = N.take(self.y, [self.pickIndex]) self.handleA.set_data(N.take(self.x, [self.pickIndex]), [paramVal]) else: paramVal = event.mouseevent.ydata self.handleA.set_data([event.mouseevent.xdata], [paramVal]) showText = '%s: %s' % (self.dataLabels[self.pickIndex], paramVal[0]) # showText = '%s: %s'%self.dataLabels[self.pickIndex] self.textHandle = self.canvas.ax.text(0.03, 0.95, showText, fontsize=9,\ bbox=dict(facecolor='yellow', alpha=0.1),\ transform=self.canvas.ax.transAxes, va='top') self.handleA.set_visible(True) self.canvas.draw() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n" % (sys.exc_type, sys.exc_value) print errorMsg
def zoom(self, *args): NavigationToolbar2QT.zoom(self, *args) self.activate_widget('zoom', not self.isZoomActivated)
class MPL_Widget(QtGui.QWidget): def __init__(self, parent = None, enableAutoScale = True, enableCSV = False, enableEdit = True, doublePlot = False, layoutDir = 'h'): QtGui.QWidget.__init__(self, parent) if doublePlot: self.canvas = DoubleMyMplCanvas() else: self.canvas = MyMplCanvas() self.toolbar = NavigationToolbar(self.canvas, self.canvas) # self.toolbar.hide() self.installEventFilter(EventFilter(self)) if layoutDir == 'v': self.toolbar.setOrientation(QtCore.Qt.Vertical) self.layout = QtGui.QHBoxLayout() elif layoutDir == 'h': self.layout = QtGui.QVBoxLayout() # self.layout.addWidget(self.canvas) # self.layout.addWidget(self.toolbar) self.layout.addWidget(self.toolbar) self.layout.addWidget(self.canvas) self.setLayout(self.layout) ########################## self.dataLabels = None ###########SAVING FIGURE TO CLIPBOARD########## self.cb = None #will be used for the clipboard self.tempPath = getHomeDir() self.tempPath = os.path.join(self.tempPath,'tempMPL.png') if enableEdit: self.enableEdit() self.lineDict = None self.addLegend = False self.x = None#used for picker self.y = None #######SAVING FIGURE DATA############################ if enableCSV: self.enableCSV() ########### HELPER FUNCTIONS ######################### self.clearPlotAction = QtGui.QAction("Clear Plot", self) self.addAction(self.clearPlotAction) QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # def focusOutEvent(self, event): # print "Focus Out" def clearPlot(self): print "Clear Plot" self.canvas.ax.cla() self.canvas.format_labels() self.canvas.draw() # def __initContextMenus__(self): # self.clearPlotAction = QtGui.QAction("Clear Plot", self) # self.addAction(self.clearPlotAction) # QtCore.QObject.connect(self, QtCore.SIGNAL("triggered()"), self.clearPlot) # # self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # self.connect(self, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.plotTabContext) # def plotTabContext(self, point): # '''Create a menu for mainTabWidget''' # plotCT_menu = QtGui.QMenu("Menu", self) # plotCT_menu.addAction(self.Zoom) # plotCT_menu.addAction(self.actionAutoScale) # plotCT_menu.addSeparator() # plotCT_menu.addAction(self.clearPlotAction) # plotCT_menu.exec_(self.mapToGlobal(point)) def focusEvent(self, event): self.enableAutoScale() self.enableZoom() self.enableClip() # self.enableCSV() #print "Focus In %s"%self.canvas.plotTitle def lossFocusEvent(self, event): self.disableAutoScale() self.disableZoom() self.disableClip() # self.disableCSV() #print "Focus Out %s"%self.canvas.plotTitle def enableClip(self): self.mpl2ClipAction = QtGui.QAction("Save to Clipboard", self) self.mpl2ClipAction.setShortcut("Ctrl+C") self.addAction(self.mpl2ClipAction) QtCore.QObject.connect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) def disableClip(self): QtCore.QObject.disconnect(self.mpl2ClipAction,QtCore.SIGNAL("triggered()"), self.mpl2Clip) self.removeAction(self.mpl2ClipAction) def enableEdit(self): self.editAction = QtGui.QAction("Edit Line Properties", self) self.editAction.setShortcut("Ctrl+Alt+E") self.addAction(self.editAction) QtCore.QObject.connect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) def disableEdit(self): if self.editAction: QtCore.QObject.disconnect(self.editAction,QtCore.SIGNAL("triggered()"), self.editPlotProperties) self.removeAction(self.editAction) def enableZoom(self): self.Zoom = QtGui.QAction("Zoom", self) self.Zoom.setShortcut("Ctrl+Z") self.addAction(self.Zoom) QtCore.QObject.connect(self.Zoom, QtCore.SIGNAL("triggered()"), self.ZoomToggle) def disableZoom(self): if self.Zoom != None: QtCore.QObject.disconnect(self.Zoom,QtCore.SIGNAL("triggered()"), self.ZoomToggle) self.removeAction(self.Zoom) def disableAutoScale(self): if self.actionAutoScale != None: QtCore.QObject.disconnect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) self.removeAction(self.actionAutoScale) def enableAutoScale(self): self.actionAutoScale = QtGui.QAction("AutoScale", self)#self.MainWindow) self.actionAutoScale.setShortcut("Ctrl+A") self.addAction(self.actionAutoScale) QtCore.QObject.connect(self.actionAutoScale,QtCore.SIGNAL("triggered()"), self.autoscale_plot) def enableCSV(self): self.saveCSVAction = QtGui.QAction("Save to CSV", self) self.saveCSVAction.setShortcut("Ctrl+Alt+S") self.addAction(self.saveCSVAction) QtCore.QObject.connect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) def disableCSV(self): QtCore.QObject.disconnect(self.saveCSVAction,QtCore.SIGNAL("triggered()"), self.save2CSV) self.removeAction(self.saveCSVAction) def setLineDict(self): self.lineDict = {} lineList = self.canvas.ax.get_lines() if lineList > 0: for line in lineList: self.lineDict[line.get_label()]=line def editPlotProperties(self): print "Edit Enabled" self.setLineDict() # if len(self.lineDict) > 0: curAx = self.canvas.ax if POD(self.lineDict, curAx = curAx, parent = self).exec_(): if self.addLegend: curAx.legend(borderaxespad = 0.03, axespad=0.25) self.canvas.format_labels() self.canvas.draw() else: print "Cancel" def ZoomToggle(self): self.toolbar.zoom() #this implements the classic zoom # if self.hZoom: # self.hZoom = False # self.span.visible = False # else: # self.hZoom = True # self.span.visible = True def autoscale_plot(self): self.toolbar.home() #implements the classic return to home # self.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True) # self.canvas.draw() # self.emit(QtCore.SIGNAL("autoScaleAxis(bool)"),True) # def onclick(self, event): # #sets up the maximum Y level to be displayed after the zoom. # #if not set then it maxes to the largest point in the data # #not necessarily the local max # if event.ydata != None: # self.localYMax = int(event.ydata) # # def onselect(self, xmin, xmax): # #print xmin, xmax # if self.hZoom: # self.canvas.ax.set_ylim(ymax = self.localYMax) # self.canvas.ax.set_xlim(xmin, xmax) # self.canvas.draw() def save2CSV(self): path = self.SFDialog() if path != None: try: lines = self.canvas.ax.get_lines() data2write = [] for line in lines: data2write.append(line.get_data()[0]) data2write.append(line.get_data()[1]) print data2write data2write = N.array(data2write) data2write.dtype = N.float32 N.savetxt(str(path), N.transpose(data2write), delimiter = ',', fmt='%.4f') except: try: #this is for the case where the data may not be in float format? N.savetxt(str(path), N.transpose(data2write), delimiter = ',') except: print 'Error saving figure data' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg def SFDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Select File to Save", "", "csv Files (*.csv)") if not fileName.isEmpty(): print fileName return fileName else: return None def removePicker(self): try: self.handleA.remove() except: print "" def setData(self, x, y): if x != None: self.x = x if y != None: self.y = y def addPicker(self): '''Sets up the plot variables used for interaction''' self.handleA, = self.canvas.ax.plot([0], [0], 'o',\ ms=8, alpha=.5, color='yellow', visible=True, label = '_nolegend_') self.is_hZoom = False self.canvas.mpl_connect('pick_event', self.OnPickPlot) def OnPickPlot(self, event): self.pickIndex = event.ind[0] try: self.textHandle.remove() except: pass self.curText = event.artist.get_label() if self.x != None and self.y != None: #I'd rather do the following ALWAYS but it seems difficult to do in terms of keeping track of which arrays were plotted when multiple plots are present paramVal = N.take(self.y, [self.pickIndex]) self.handleA.set_data(N.take(self.x, [self.pickIndex]), [paramVal]) else: paramVal = event.mouseevent.ydata self.handleA.set_data([event.mouseevent.xdata], [paramVal]) showText = '%s: %s'%(self.dataLabels[self.pickIndex],paramVal[0]) # showText = '%s: %s'%self.dataLabels[self.pickIndex] self.textHandle = self.canvas.ax.text(0.03, 0.95, showText, fontsize=9,\ bbox=dict(facecolor='yellow', alpha=0.1),\ transform=self.canvas.ax.transAxes, va='top') self.handleA.set_visible(True) self.canvas.draw() def mpl2Clip(self): try: self.canvas.fig.savefig(self.tempPath) tempImg = QtGui.QImage(self.tempPath) self.cb = QtGui.QApplication.clipboard() self.cb.setImage(tempImg) except: print 'Error copying figure to clipboard' errorMsg = "Sorry: %s\n\n:%s\n"%(sys.exc_type, sys.exc_value) print errorMsg