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()
Example #2
0
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()
Example #3
0
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)
Example #4
0
 def zoom(self, *args):
     NavigationToolbar2QT.zoom(self, *args)
     self.activate_widget('zoom', not self.isZoomActivated)
Example #5
0
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()
Example #6
0
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)
Example #7
0
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()
Example #8
0
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
Example #9
0
 def zoom(self, *args):
   NavigationToolbar2QT.zoom(self, *args)
   self.activate_widget('zoom', not self.isZoomActivated)
Example #10
0
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