Exemplo n.º 1
0
class FigureWidget(QtGui.QWidget):
    """ A QWidget that contains a matplotlib plot that plots a matrix as a
    series of line plots.
    """

    def __init__(self, parent=None):
        super(FigureWidget, self).__init__(parent)
        self.fig = plt.Figure()
        self.setMinimumSize(500,300)
        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.setParent(self)
        self.create_plots(1)
        # set the plot background color to the window background color
        color = QtGui.QPalette().window().color()
        self.fig.set_facecolor((color.redF(), color.greenF(), color.blueF()))
        self.canDraw = True

    def create_plots(self, num_plots):
        """ Create enough subplots to hold `num_plots` plots. """
        self.canDraw = False
        self.fig.clear()
        self.axes = [self.fig.add_subplot(1,num_plots,n+1)
                     for n in range(num_plots)]
        self.lines = [ax.plot(numpy.zeros(1024))[0] for ax in self.axes]
        for ax in self.axes:
            ax.set_ylim((-1,1))
            ax.set_xlim((0,1024))
            # move the spines out of the plot araea so it won't get
            # clobbered by the partial redrawing during `self.draw()`.
            ax.spines['bottom'].set_position(('outward', 5))
            ax.spines['left'].set_position(('outward', 5))
            ax.spines['right'].set_visible(False)
            ax.spines['top'].set_visible(False)
        self.fig.tight_layout()
        self.canvas.draw()
        self.canDraw = True

    def resizeEvent(self, event):
        """ Scale the figure in tandem with the widget. """
        self.fig.set_size_inches(self.width()/80, self.height()/80)
        self.canvas.draw()

    def showEvent(self, event):
        """ Called on the first draw. Sets up the correct window geometry. """
        self.resizeEvent(None)

    def draw(self, data):
        """ Update the plots as quickly as possible. """
        if not self.canDraw: return()
        for n in range(data.shape[1]):
            self.lines[n].set_ydata(data[:,n])
            self.axes[n].draw_artist(self.axes[n].patch)
            self.axes[n].draw_artist(self.lines[n])
        self.canvas.update()
Exemplo n.º 2
0
class FigureWidget(QtGui.QWidget):
    """ A QWidget that contains a matplotlib plot that plots a matrix as a
    series of line plots.
    """
    def __init__(self, parent=None):
        super(FigureWidget, self).__init__(parent)
        self.fig = plt.Figure()
        self.setMinimumSize(500, 300)
        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.setParent(self)
        self.create_plots(1)
        # set the plot background color to the window background color
        color = QtGui.QPalette().window().color()
        self.fig.set_facecolor((color.redF(), color.greenF(), color.blueF()))
        self.canDraw = True

    def create_plots(self, num_plots):
        """ Create enough subplots to hold `num_plots` plots. """
        self.canDraw = False
        self.fig.clear()
        self.axes = [
            self.fig.add_subplot(1, num_plots, n + 1) for n in range(num_plots)
        ]
        self.lines = [ax.plot(numpy.zeros(1024))[0] for ax in self.axes]
        for ax in self.axes:
            ax.set_ylim((-1, 1))
            ax.set_xlim((0, 1024))
            # move the spines out of the plot araea so it won't get
            # clobbered by the partial redrawing during `self.draw()`.
            ax.spines['bottom'].set_position(('outward', 5))
            ax.spines['left'].set_position(('outward', 5))
            ax.spines['right'].set_visible(False)
            ax.spines['top'].set_visible(False)
        self.fig.tight_layout()
        self.canvas.draw()
        self.canDraw = True

    def resizeEvent(self, event):
        """ Scale the figure in tandem with the widget. """
        self.fig.set_size_inches(self.width() / 80, self.height() / 80)
        self.canvas.draw()

    def showEvent(self, event):
        """ Called on the first draw. Sets up the correct window geometry. """
        self.resizeEvent(None)

    def draw(self, data):
        """ Update the plots as quickly as possible. """
        if not self.canDraw: return ()
        for n in range(data.shape[1]):
            self.lines[n].set_ydata(data[:, n])
            self.axes[n].draw_artist(self.axes[n].patch)
            self.axes[n].draw_artist(self.lines[n])
        self.canvas.update()
Exemplo n.º 3
0
class mpl_widget(QWidget):
    def __init__(self, parent=None, mainWidget=None):
        self._SELECTEDCELLS = list()       # container for instances of selected cells, so we can delete them when we want
        self._SELECTEDCELLS_IJ = list()  # container for coords of selected cells, so we can delete them when we want
        self._SELECTEDCELLLINES = list()   # container for instances of selected cells, so we can delete them when we want
        self._GRIDLINES = None
        QWidget.__init__(self, parent)
        self.mainWidget = mainWidget
        self.create_main_frame()
        self.mpl_menu = mpl_menu(self)
        self.shift_is_held = False
        #self.connect(self.mpl_menu, QtCore.SIGNAL('mySignal'), self.mySlot)
        #print 'my parent is:', parent
        self.clear_selection()
        self.init_tooltips()

    def init_tooltips(self):
        self.canvas.setToolTip('If 2D plot => RMB click toggles menu <br> - RMB click selects cell <br> - selected cells are drawn with black border')
        self.grid_cb.setToolTip('If 2D plot => show computational grid <br> If 1D plot => show normal gridlines')
        self.cbar_button.setToolTip('If 2D plot => controls the color range. <br> Note: <br> - pressing UP and DOWN arrows cycles through colormaps <br> - dragging colorbar with RMB scales the color-range <br> - dragging colorbar with LMB shifts the color-range')
        self.mpl_toolbar.setToolTip('Shows coordinates (i,j, lat,lon) and data-value(z) under the cursor. <br> if you see <i>>>></i> coordinates are not visible. Enlarge the window')

    def create_main_frame(self):

        self.fig = Figure(dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy( Qt.ClickFocus )
        self.canvas.setFocus()

        self.mpl_toolbar = myNavigationToolbar(self.canvas, self)
        self.canvas.mpl_connect('button_press_event', self.on_click)
        self.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.canvas.mpl_connect('key_release_event', self.on_key_release)
        #self.canvas.mpl_connect('button_press_event', self.disable_clicks)


        self.cbar_button = QPushButton("Color Range")
        self.cbar_button.setFocusPolicy( Qt.NoFocus )
        self.grid_cb = QCheckBox("Show Grid")
        self.grid_cb.setFocusPolicy( Qt.NoFocus )
        self.grid_cb.stateChanged.connect(self.showGrid)

        vbox = QVBoxLayout()
        hbox = QHBoxLayout()

        vbox.addWidget(self.canvas)  # the matplotlib canvas
        hbox.addWidget(self.mpl_toolbar)
        hbox.addWidget(self.cbar_button)
        hbox.addWidget(self.grid_cb)
        vbox.addLayout(hbox)
        self.setLayout(vbox)



    def on_click(self, event):
        if event.inaxes != self.get_axes()[0]: return
        #if self.get_axes()[0].format_coord(event.x, event.y) == 'outside data area': return
        if self.allow_menu():
            self.allow_popup_menu = True
            if self.shift_is_held:
                self.allow_popup_menu = False

            point = [int(event.xdata + .5), int(event.ydata + .5)]
            #print '>>>', point, '\t currently {0} selected'.format(len(self._SELECTEDCELLS))
            if event.button == 3 :  #if RMB is clicked

                # working with dialog for transect!
                if self.mainWidget.transect_dlg:
                    if self.mainWidget.transect_dlg.toogle_show_after_selected_cell:
                        realx, realy = self.get_real_xy(event.xdata, event.ydata, self.mainWidget.detect_variable_dimensions())
                        realpoint = [realy, realx]
                        #print 'real xy:', realpoint
                        if self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p1(realpoint)
                        elif self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p2(realpoint)

                        self.mainWidget.transect_dlg.update()
                        self.mainWidget.transect_dlg.show()
                
                # working with dialog for flux!
                if self.mainWidget.flux_dlg:
                    if self.mainWidget.flux_dlg.toogle_show_after_selected_cell:
                        if self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p1(point)
                        elif self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p2(point)

                        self.mainWidget.flux_dlg.update()
                        self.mainWidget.flux_dlg.show()



                if len(self._SELECTEDCELLS) == 0:  # if no cell is selected
                    self.add_selected_cell(point)


                else:  # if some cells are already selected
                    if self.mpl_menu.allow_rmb_select_cells() or self.shift_is_held:
                        # check if this point is already selected:
                        already_selected = False
                        for p in self._SELECTEDCELLS_IJ:
                            if (point[0] == p[0]) and (point[1] == p[1]):
                                already_selected = True
                                print 'cell already selected... is not added'

                        if not already_selected:
                            self.add_selected_cell(point)
                    else:
                        pass
                        #self.clear_selection()
                        #self.add_selected_cell(point)

    def cells_selected(self):
        if self._SELECTEDCELLS: return len(self._SELECTEDCELLS)
        else: return False

    def add_selected_cell(self, point):
        ''' point = [i, j]'''
        print 'selected cell:', point[0], point[1]
        c = self.draw_picked_cell(point)
        self._SELECTEDCELLS.append(c)
        self._SELECTEDCELLS_IJ.append(point)




    def get_selected_cells_ij(self):
        return self._SELECTEDCELLS_IJ

    def clear_selection(self):
        '''
        delete all graphical objects of selected cells
        redraw canvas
        '''
        print 'clearing stuff'
        if len(self._SELECTEDCELLLINES) > 0:
            for line in self._SELECTEDCELLLINES:
                l = line.pop(0)
                l.remove()
                del l
            del self._SELECTEDCELLLINES[:]
        #print 'cells ---- before:', len(self._SELECTEDCELLS)
        if len(self._SELECTEDCELLS) > 0:
            for cell in self._SELECTEDCELLS:
                for line in cell:
                    l = line.pop(0)
                    l.remove()
                    del l
            del self._SELECTEDCELLS[:]
        #print 'cells ---- left:', len(self._SELECTEDCELLS)


        #print 'cells-coords ----'
        #print len(self._SELECTEDCELLS_IJ)
        if self._SELECTEDCELLS_IJ:
            for cellcoords in self._SELECTEDCELLS_IJ:
                #cc = cellcoords.pop(0)
                #cellcoords.remove()
                del cellcoords
            del self._SELECTEDCELLS_IJ[:]
        #print 'cells ---- left,', len(self._SELECTEDCELLS_IJ)



        if len(self._SELECTEDCELLS) != 0:
            raise ValueError('List "self._SELECTEDCELLS" was not flushed')

        if len(self._SELECTEDCELLLINES) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')

        if len(self._SELECTEDCELLS_IJ) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')
        # update plot
        self.canvas.draw()
        #print 'finishing clear: cells left', len(self._SELECTEDCELLS)


    def showGrid(self, state):
        if self.fig.axes:
            current_plot = self.mainWidget.get_plotType()
            current_plot2D = self.mainWidget.get_plotType_for_timeseries()
            if state == Qt.Checked:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(True)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(True)
            else:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(False)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(False)
            self.canvas.draw()

    def draw_picked_cell(self, point):
        x = point[0]
        y = point[1]
        '''
        approach drawing a patch... not working
        cell_bnd = patches.Rectangle((x-.5, y-.5), 1, 1, fill=False, edgecolor="black", hatch=None, linewidth=1.)
        cell_instance = self.fig.axes[0].add_patch(cell_bnd)
        '''

        b_line = [(x-.5, x+.5), (y-.5, y-.5)]
        r_line = [(x+.5, x+.5), (y-.5, y+.5)]
        t_line = [(x-.5, x+.5), (y+.5, y+.5)]
        l_line = [(x-.5, x-.5), (y-.5, y+.5)]
        cell = [b_line, r_line, t_line, l_line]
        for i, l in enumerate(cell):
            ll = self.fig.axes[0].plot(l[0], l[1], 'k-', lw=.8)
            cell[i] = ll  # overwriting current Line2D object with object binded to an axes
        #self._SELECTEDCELLS.append(cell)  # collecting reference to this cell to be able to delete it
        #self._SELECTEDCELLS_IJ.append(point)  # collecting reference to this cell to be able to delete it

        self.canvas.draw()
        return cell


    def draw_line(self, point1, point2):
        line = [(point1[0], point2[0]), (point1[1], point2[1])]
        l = self.fig.axes[0].plot(line[0], line[1], 'k-', lw=2)
        return l

    def draw_pixel_grid(self, enable=True):
        if enable:
            dx = 1
            dy = 1
            x0 = -.5
            y0 = -.5

            if self.mainWidget.get_plotType_for_timeseries() == '2DXY':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nY()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZY':
                nx = self.mainWidget.get_nY()
                ny = self.mainWidget.get_nZ()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZX':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nZ()

            self._GRIDLINES = list()
            for n_hline in np.arange(ny+1):
                hline = [(x0, x0+nx), (y0+n_hline, y0+n_hline)]
                l = self.fig.axes[0].plot(hline[0], hline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it

            for n_vline in np.arange(nx+1):
                vline = [(x0+n_vline, x0+n_vline), (y0, y0+ny)]
                l = self.fig.axes[0].plot(vline[0], vline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it


        if not enable:
            #print 'deleting lines...'
            if self._GRIDLINES:  # if lines were created
                #print 'lines are here...'
                for line in self._GRIDLINES:
                    #print line
                    l = line.pop(0)
                    l.remove()
                    del l
            self.fig.canvas.draw()

    def on_key_press(self, event):
        #print 'key pressed:', event.key
        if event.key == 'shift':
            self.shift_is_held = True


    

    def on_key_release(self, event):
        #print 'key released:', event.key
        if event.key == 'shift':
            self.shift_is_held = False

        elif event.key == 'escape':
            self.clear_selection()


    def change_coordinate_formatter(self, ax, data2d,  bruteforce_flag=None, bruteforce_dims=None):
        ''' see http://stackoverflow.com/questions/14754931/matplotlib-values-under-cursor
        '''
        numrows, numcols = data2d.shape
        bruteforce_mode_on = False
        bruteforce_mode_on = (bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2])


        def format_coord(x, y):
            col = int(x+0.5)
            row = int(y+0.5)

            if not bruteforce_mode_on:
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    return 'i=%d j=%d z=%.6f' % (col, row, z)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'

            elif bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2]:
                '''
                our extend in X=[-0.5:numcols-0.5], Y=[-0.5:numrows-0.5], because col,row is cell center!
                '''
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    real_x, real_y = self.get_real_xy(x, y, bruteforce_dims)

                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    #return 'i=%d j=%d z=%.3f x=%.4f y=%.4f' % (col, row, z, real_x, real_y)
                    return 'i=%d j=%d z=%.3f, %s=%.2f %s=%.2f' % (
                        col, row, z, bruteforce_dims[-1], real_x, bruteforce_dims[-2], real_y)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'
            else:
                raise ValueError('bruteforce_flag can be $None$ or $"2DXY"$. Passed %s' % bruteforce_flag)
        ax.format_coord = format_coord


    def allow_menu(self):
        allow = False
        #print "self.mainWidget.get_plotType():", self.mainWidget.get_plotType()
        #print "self.mainWidget.get_plotType_for_timeseries():", self.mainWidget.get_plotType_for_timeseries()
        if self.mainWidget.get_plotType() == "2D" and not self.mainWidget.get_plotType_for_timeseries() == "2DZT":
            allow = True
        return allow
    

    def get_real_xy(self, i, j, dimension_list):
        '''
        functions returns values of x,y based on passed indexes i, j

        '''
        if any(dimension_list[-2:-1]) is None:
            print 'Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)'
            raise ValueError('Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)')
        nc = self.mainWidget.get_selected_ncfile_instance()
        try:
            x_var = nc.variables[dimension_list[-1]]
            y_var = nc.variables[dimension_list[-2]]
            
        except:
            
            print ('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))
            raise ValueError('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))


        x_ratio = (x_var[-1]-x_var[0])/(len(x_var)-1)
        y_ratio = (y_var[-1]-y_var[0])/(len(y_var)-1)

        #x[i] = x_var[0]+x_ratio*i
        #y[j] = y_var[0]+y_ratio*j
        x = x_var[0] + x_ratio*i
        y = y_var[0] + y_ratio*j
        nc.close()
        return (x, y)

    def get_axes(self):
        return self.fig.get_axes()
    

    def fast_redraw(self, artist):
        background = [self.canvas.copy_from_bbox(self.get_axes()[0].bbox)]
        self.get_axes()[0].draw_artist(artist)
        self.canvas.restore_region(background)
        self.canvas.blit(self.get_axes()[0].bbox)
        self.canvas.update()
        self.canvas.flush_events()
Exemplo n.º 4
0
class AniWindow(QtWidgets.QDialog):
    ## Class to create animation object that plots real-time voltage vs time

    def __init__(self, fs, N_samples):
        super(AniWindow, self).__init__()
        self.fs = fs
        self.N_samples = N_samples

        ## Animation figure
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)

        ## Animate button
        self.button = QtWidgets.QPushButton('Animate')
        self.button.clicked.connect(self.animate)

        ## Set the layout
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def animate(self):
        ## Animation figure settings
        self.ax = self.fig.add_subplot(111)
        self.line, = self.ax.plot([], [], lw=1)
        self.ax.grid()
        self.ax.set_ylim(-0.5, 0.5)
        self.ax.set_xlim(0, .2)
        self.ax.set_xlabel('X [m]')
        self.ax.set_ylabel('Y [m]')
        self.xdata, self.ydata = [], []

        mag = 100  ## Magnify tip displacements
        self.ax.set_title(
            'Real-Time Tip Displacement of Beam, Magnification Factor of ' +
            str(mag))

        def modeShapes(L):
            ## Generate first mode of a cantilever beam
            alpha = np.zeros(1)
            R = np.zeros(1)

            x = np.arange(0.0, L + 0.01, 0.01)
            PHI = np.zeros([1, len(x)])

            for t in range(len(alpha)):
                if t == 0:
                    alpha[t] = 0.59686 * np.pi
                elif t == 1:
                    alpha[t] = 1.49418 * np.pi

                R[t] = (cos(alpha[t]) + cosh(alpha[t])) / (sin(alpha[t]) +
                                                           sinh(alpha[t]))
                PHI[t] = cosh(alpha[t] * x / L) - cos(
                    alpha[t] * x / L) + R[t] * (sin(alpha[t] * x / L) -
                                                sinh(alpha[t] * x / L))
            return PHI

        def data_gen(t=0):
            ## Generate real-time tip displacement
            run = Measurement(
                fs=self.fs,
                active_channels=[0, 1])  ## Instance of measurement class
            cnt = 0
            while cnt < self.N_samples:
                cnt = cnt + 1
                ## Make beam points and mode shape
                L = 15 / 100
                zero_displ_V = 1.9
                x = np.arange(0.0, L + .01, 0.01)
                PHI = modeShapes(L)

                ## Get real-time tip displacement
                data_loop(run)  ## Adds point to end of vtime and data list
                tip_displ = (run.data[-1][1] - zero_displ_V
                             ) / 1000  ## CONVERSION: 1mm / V * 1m/1000mm
                print(x)
                print(PHI[0] * tip_displ * mag)
                yield x, PHI[0] * tip_displ * mag

        ## ~Run animation functioion~
        self.anim = animation.FuncAnimation(self.fig,
                                            self.animate_loop,
                                            data_gen,
                                            blit=True,
                                            interval=.001,
                                            repeat=False,
                                            init_func=self.initial)
        ## Update figure in GUI
        self.canvas.update()

    def initial(self):
        ## Clear data
        self.line.set_data([], [])

        return self.line,

    def animate_loop(self, data):
        ## Update data
        x, y = data
        self.xdata = x
        self.ydata = y
        self.line.set_data(self.xdata, self.ydata)

        return self.line,
Exemplo n.º 5
0
class mGraph(QtGui.QWidget):
    def __init__(self, device, parent=None):
        QtGui.QWidget.__init__(self, parent)
        # Create a matplotlib figure.
        self.figure = plt.figure()
        self.figure.set_facecolor('r')
        # Create a QFrame to house the plot. This is not necessary,
        # just makes it look nice.
        self.matframe = QtGui.QFrame()
        self.matLayout = QtGui.QVBoxLayout()
        self.matLayout.setSpacing(0)
        self.matframe.setLayout(self.matLayout)
        self.matframe.setFrameShape(QtGui.QFrame.Panel)
        self.matframe.setFrameShadow(QtGui.QFrame.Plain)
        self.matframe.setStyleSheet(
            "background-color: rgb(70,80,88); "
            "margin:0px; border:2px solid rgb(0, 0, 0); ")
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred,
                                  QtGui.QSizePolicy.Preferred)
        # This is the device we want to use.
        self.device = device
        # This sets up axis on which to plot.
        color = (189. / 255, 195. / 255, 199. / 255)
        self.ax = self.figure.add_subplot(111, axisbg=color)
        ax = self.ax
        # Add the matplotlib canvas to the QFrame.
        self.matLayout.addWidget(self.canvas)
        # The following lines set up all the colors, makes it look nice.
        # The code to do it is far from pretty and I am planning
        # on cleaning this up a bit.
        self.figure.patch.set_color((70. / 255, 80. / 255, 88. / 255))
        self.figure.patch.set_edgecolor((70. / 255, 80. / 255, 88. / 255))
        ax.spines['bottom'].set_color(color)
        ax.spines['top'].set_color(color)
        ax.spines['right'].set_color(color)
        ax.spines['left'].set_color(color)
        ax.tick_params(axis='x', colors=color)
        ax.tick_params(axis='y', colors=color)
        ax.title.set_color(color)
        ax.yaxis.label.set_color(color)
        ax.xaxis.label.set_color(color)
        ax.xaxis.get_offset_text().set_color(color)
        ax.yaxis.get_offset_text().set_color(color)
        # This is an array of all the lines on the plot. A line for
        # every parameter.
        self.line = []
        self.mins = 0
        self.maxes = 1
        # Each element of line holds a plot, to be combined onto
        # the same graph.
        self.line.append(ax.plot(1, 1, label="Getting Data...")[0])

        # In order to handle interactivity, I had to do some odd stuff
        # with the toolbar buttons: self.home holds the original
        # function called when the home button on the toolbar
        # is clicked.
        self.home = NavigationToolbar.home
        # We now change the function that is called when the toolbar is
        # clicked.
        NavigationToolbar.home = self.enableAutoScaling
        self.toolbar = NavigationToolbar(self.canvas, self)

        self.cid = self.canvas.mpl_connect('button_press_event',
                                           self.disableAutoScaling)
        self.setStyleSheet("QPushButton{\
                    color:rgb(189,195, 199); \
                    background:rgb(70, 80, 88)};")
        self.fullGraphBtn = QtGui.QPushButton("Show Interactive Graph")
        self.fullGraphBtn.clicked.connect(self.openFullGraphGui)
        self.toolbarFrame = QtGui.QFrame()
        toolbarFrameLayout = QtGui.QVBoxLayout()
        toolbarFrameLayout.addWidget(self.toolbar)
        self.toolbar.setParent(None)
        self.toolbarFrame.setLayout(toolbarFrameLayout)
        self.toolbarFrame.setStyleSheet("\
                   border:2px solid rgb(0,0,0);\
                   color:rgb(189,195,199); \
                   background:rgb(70, 80, 88);")
        self.toolbar.setStyleSheet("\
                   border:0px solid rgb(0,0,0);\
                   QDialog{background:rgb(70, 80, 88)}")
        self.matPlotInfo = QtGui.QLabel()
        self.alertFont = QtGui.QFont()
        self.alertFont.setPointSize(12)
        self.matPlotInfo.setStyleSheet("color:rgb(200, 69, 50);")
        self.matPlotInfo.setText("Auto refresh disabled, "
                                 "click HOME button to enable.")
        self.matPlotInfo.setFont(self.alertFont)

        #self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.timer = QtCore.QTimer(self)

        self.hidden = True
        self.home = True
        self.initialized = False
        self.currTimeRange = 120
        self.lineSelect = MCheckableComboBox()
        self.lineSelect.setSizeAdjustPolicy(0)
        self.lineSelect.setStyleSheet("\
                    background-color:rgb(70, 80, 88);\
                    color:rgb(189,195, 199);")
        self.plot(self.currTimeRange)

        self.timer.timeout.connect(partial(self.plot, self.currTimeRange))
        self.timer.start(self.refreshRateSec * 1000)

        # Did it store data?
        self.dataOk = True
        self.hideButton = QtGui.QPushButton("Show Plot")
        self.hideButton.clicked.connect(self.togglePlot)
        self.oneMinButton = QtGui.QPushButton("1 min")
        self.oneMinButton.clicked.connect(partial(self.plot, 60))
        self.tenMinButton = QtGui.QPushButton("10 min")
        self.tenMinButton.clicked.connect(partial(self.plot, 600))
        self.twoHrButton = QtGui.QPushButton("2 hr")
        self.twoHrButton.clicked.connect(partial(self.plot, 7200))
        self.twelveHrButton = QtGui.QPushButton("12 hr")
        self.twelveHrButton.clicked.connect(partial(self.plot, 43200))
        self.threeDayButton = QtGui.QPushButton("3 day")
        self.threeDayButton.clicked.connect(partial(self.plot, 259200))
        self.oneWkButton = QtGui.QPushButton("1 week")
        self.oneWkButton.clicked.connect(partial(self.plot, 604800))
        self.allButton = QtGui.QPushButton("All Time")
        self.allButton.clicked.connect(partial(self.plot, None))

        self.canvas.hide()
        self.toolbar.hide()

        # Set the layout.
        buttonLayout1 = QtGui.QHBoxLayout()
        buttonLayout1.addWidget(self.hideButton)
        buttonLayout1.addWidget(self.fullGraphBtn)
        buttonLayout1.addStretch(0)
        buttonLayout2 = QtGui.QHBoxLayout()
        settingsbuttons1 = QtGui.QHBoxLayout()

        buttonLayout2.addWidget(self.oneMinButton)
        buttonLayout2.addWidget(self.tenMinButton)
        buttonLayout2.addWidget(self.twoHrButton)
        buttonLayout2.addWidget(self.twelveHrButton)
        buttonLayout2.addWidget(self.threeDayButton)
        buttonLayout2.addWidget(self.oneWkButton)
        buttonLayout2.addWidget(self.allButton)
        buttonLayout2.addStretch(0)
        self.oneMinButton.hide()
        self.tenMinButton.hide()
        self.twoHrButton.hide()
        self.twelveHrButton.hide()
        self.threeDayButton.hide()
        self.oneWkButton.hide()
        self.allButton.hide()
        self.lineSelect.hide()
        self.matframe.hide()
        self.matPlotInfo.hide()
        self.toolbarFrame.hide()

        settingsbuttons1.addWidget(self.lineSelect)
        layout = QtGui.QVBoxLayout()
        allButtonsLayout = QtGui.QHBoxLayout()
        timeButtonsLayout = QtGui.QVBoxLayout()
        allButtonsLayout.addLayout(timeButtonsLayout)
        layout.addLayout(allButtonsLayout)
        allButtonsLayout.addLayout(settingsbuttons1)
        timeButtonsLayout.addLayout(buttonLayout1)
        timeButtonsLayout.addLayout(buttonLayout2)
        timeButtonsLayout.addWidget(self.matPlotInfo)
        layout.addWidget(self.matframe)
        layout.addWidget(self.toolbarFrame)

        self.setLayout(layout)

    def enableAutoScaling(self):
        self.timer.start(self.refreshRateSec * 1000)
        self.home = True
        self.matPlotInfo.hide()
        self.plot(self.currTimeRange)

    def disableAutoScaling(self, event):
        self.home = False
        self.matPlotInfo.show()
        self.canvas.update()
        self.timer.stop()

    def togglePlot(self):
        if not self.hidden:
            self.canvas.hide()
            self.toolbar.hide()
            self.oneMinButton.hide()
            self.tenMinButton.hide()
            self.twoHrButton.hide()
            self.twelveHrButton.hide()
            self.threeDayButton.hide()
            self.oneWkButton.hide()
            self.allButton.hide()
            self.matPlotInfo.hide()
            self.matframe.hide()
            self.lineSelect.hide()
            self.toolbarFrame.hide()
            self.timer.stop()
            self.hideButton.setText("Show Plot")
            self.hidden = True
        elif self.hidden:
            self.canvas.show()
            self.toolbar.show()
            self.oneMinButton.show()
            self.tenMinButton.show()
            self.twoHrButton.show()
            self.twelveHrButton.show()
            self.threeDayButton.show()
            self.oneWkButton.show()
            self.allButton.show()
            self.plot(self.currTimeRange)
            self.matframe.show()
            self.lineSelect.show()
            self.toolbarFrame.show()
            self.timer.start(self.refreshRateSec * 1000)
            self.hideButton.setText("Hide Plot")
            self.enableAutoScaling()
            self.hidden = False

    def initializePlot(self, dataSet):
        if dataSet:
            varNames = dataSet.getVariables()
            varNames = [varNames[1][i][0] for i in range(len(varNames[1]))]
            self.dropdownFont = QtGui.QFont()
            self.dropdownFont.setPointSize(12)
        if dataSet is not None:
            self.initialized = True
            self.line[0].remove()
            self.line = []

            for i in range(len(varNames)):
                self.line.append(self.ax.plot(1, 1, label=varNames[i])[0])
                text = QtCore.QString(varNames[i])
                self.lineSelect.addItem(text)
                self.lineSelect.setFont(self.dropdownFont)
                self.lineSelect.setChecked(i, True)

    def changeIndependenVarRange(self, timeRange):
        if not self.hidden:
            if timeRange != self.currTimeRange:
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(
                    lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            plotRefreshRate = self.device.getFrame().getPlotRefreshRate()
            if self.refreshRateSec != plotRefreshRate:
                self.refreshRateSec = plotRefreshRate
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(
                    lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)

    def getDataRangeFromDataSet(self, dataSet, time):
        if dataSet:
            data = dataSet.getData()
            i = len(data) - 1
            if time:
                while data[i][0] > (data[-1][0] - time):
                    i -= 1
                    if -1 * i > len(data):
                        return data
                data = data[i:-1]
            return data
        else:
            return None

    def openFullGraphGui(self):
        # print "opening full graph gui."
        dataSet = self.device.getFrame().getDataSet().getData()
        # print dataSet
        times = [dt.datetime.fromtimestamp(elem[0]) for elem in dataSet]
        vars = self.device.getFrame().getDataSet().getVariables()

        self.fullgraphcont = fullGraphContainer(times, vars, dataSet)
        self.fullgraphcont.show()

    def plot(self, time):
        times = None
        self.changeIndependenVarRange(time)
        dataSet = self.device.getFrame().getDataSet()

        if not self.initialized:
            self.initializePlot(dataSet)
            self.legend = self.ax.legend(loc='upper left')
            # This is the ONLY time canvas.draw is called. It should
            # NOT be called anywhere else if the graphing speed is
            # to be fast.
            self.canvas.draw()
        else:
            data = self.getDataRangeFromDataSet(dataSet, time)
            for i in range(len(data[0]) - 1):
                if self.lineSelect.isChecked(i):
                    times = [dt.datetime.fromtimestamp(row[0]) for row in data]
                    column = [row[i + 1] for row in data]
                    if not self.line[i].get_visible():
                        self.line[i].set_visible(True)
                    self.line[i].set_data(times, column)
                    self.legend = self.ax.legend(loc='upper left')
                    self.ax.grid(True)
                    self.ax.hold(True)
                else:
                    self.line[i].set_visible(False)
                pass
            self.ax.set_title(self.device.getFrame().getTitle(),
                              color=(189. / 255, 195. / 255, 199. / 255))
            if self.home and times:
                self.ax.set_xlim(times[0], times[-1])
                self.ax.relim(visible_only=True)
                self.ax.autoscale(axis='y')

            frame = self.device.getFrame()
            yLabel = frame.getYLabel()
            if yLabel is not None:
                if frame.getCustomUnits():
                    self.ax.set_ylabel("%s (%s)" %
                                       (yLabel, frame.getCustomUnits()))
                elif frame.getUnits()[i - 1]:
                    self.ax.set_ylabel("%s (%s)" %
                                       (yLabel, frame.getUnits()[i - 1]))

            locator = AutoDateLocator()

            self.ax.xaxis.set_major_locator(locator)
            self.ax.xaxis.set_major_formatter(DateFormatter('%m/%d %H:%M:%S'))
            self.figure.autofmt_xdate()
            self.ax.draw_artist(self.figure)
            self.ax.draw_artist(self.ax.patch)
            self.ax.draw_artist(self.ax.yaxis)
            self.ax.draw_artist(self.ax.xaxis)

            for i, line in enumerate(self.line):
                self.ax.draw_artist(line)

            self.ax.set_xlabel("Time")
            self.ax.draw_artist(self.legend)

            self.canvas.update()

            self.canvas.flush_events()
Exemplo n.º 6
0
class mGraph(QtGui.QWidget):
    def __init__(self, device, parent=None):
        QtGui.QWidget.__init__(self, parent)
        # Create a matplotlib figure
        self.figure = plt.figure()
        self.figure.set_facecolor("r")
        # Create a QFrame to house the plot. This is not necessary, just makes it look nice
        self.matframe = QtGui.QFrame()
        self.matLayout = QtGui.QVBoxLayout()
        self.matLayout.setSpacing(0)
        self.matframe.setLayout(self.matLayout)
        self.matframe.setFrameShape(QtGui.QFrame.Panel)
        self.matframe.setFrameShadow(QtGui.QFrame.Plain)
        self.matframe.setStyleSheet("background-color: rgb(70,80,88); margin:0px; border:2px solid rgb(0, 0, 0); ")
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        # This is the device we want to use
        self.device = device
        # This sets up axis on which to plot
        self.ax = self.figure.add_subplot(111, axisbg=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        # Add the matplotlib canvas to the QFrame
        self.matLayout.addWidget(self.canvas)
        # The following lines set up all the colors, makes it look nice. The code to do it is
        # far from pretty and I am planning on cleaning this up a bit.
        self.figure.patch.set_color((70.0 / 255, 80.0 / 255, 88.0 / 255))
        self.figure.patch.set_edgecolor((70.0 / 255, 80.0 / 255, 88.0 / 255))
        self.ax.spines["bottom"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["top"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["right"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.spines["left"].set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.tick_params(axis="x", colors=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.tick_params(axis="y", colors=(189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.title.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.yaxis.label.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.xaxis.label.set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.xaxis.get_offset_text().set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        self.ax.yaxis.get_offset_text().set_color((189.0 / 255, 195.0 / 255, 199.0 / 255))
        # This is an array of all the lines on the plot. A line for every parameter
        self.line = []
        # Each element of line holds a plot, to be combined onto the same graph
        self.line.append(self.ax.plot(1, 1, label="Getting Data...")[0])
        # This is the ONLY time canvas.draw is called. It should NOT be called anywhere else if
        # the graphing speed is to be fast.
        self.canvas.draw()
        # In order to handle interactivity, I had to do some odd stuff with the
        # toolbar buttons. Self.home holds the original function called when the home button on the toolbar
        # is clicked.
        self.home = NavigationToolbar.home
        # We now change the function that is called when the toolbar is clicked.
        NavigationToolbar.home = self.enableAutoScaling
        self.toolbar = NavigationToolbar(self.canvas, self)
        # print [item for item in dir(self.toolbar) if type(item) == QtGui.QDialog]
        self.cid = self.canvas.mpl_connect("button_press_event", self.disableAutoScaling)
        self.setStyleSheet(
            "QPushButton{\
                    color:rgb(189,195, 199); \
                    background:rgb(70, 80, 88)}"
        )
        self.toolbarFrame = QtGui.QFrame()
        toolbarFrameLayout = QtGui.QVBoxLayout()
        toolbarFrameLayout.addWidget(self.toolbar)
        self.toolbar.setParent(None)
        self.toolbarFrame.setLayout(toolbarFrameLayout)
        self.toolbarFrame.setStyleSheet(
            "\
                    border:2px solid rgb(0,0,0);\
                    color:rgb(189,195,199); \
                    background:rgb(70, 80, 88);\
                    "
        )
        self.toolbar.setStyleSheet(
            "\
                    border:0px solid rgb(0,0,0);\
                    QDialog{background:rgb(250, 80, 88)}\
                    "
        )
        # print dir(self.toolbar)
        # print self.toolbar.children()
        # print self.toolbar.setPalette
        self.matPlotInfo = QtGui.QLabel()
        self.alertFont = QtGui.QFont()
        self.alertFont.setPointSize(12)
        self.matPlotInfo.setStyleSheet("color:rgb(200, 69, 50);")
        self.matPlotInfo.setText("Auto refresh disabled, click HOME button to enable.")
        self.matPlotInfo.setFont(self.alertFont)

        self.refreshRateSec = device.getFrame().getPlotRefreshRate()
        self.timer = QtCore.QTimer(self)

        self.hidden = True
        self.home = True
        self.currTimeRange = 120
        self.plot(self.currTimeRange)

        self.timer.timeout.connect(partial(self.plot, self.currTimeRange))
        self.timer.start(self.refreshRateSec * 1000)
        # did it store data?
        self.dataOk = True
        self.hideButton = QtGui.QPushButton("Show Plot")
        self.hideButton.clicked.connect(self.togglePlot)
        self.thrtysecButton = QtGui.QPushButton("30 Sec")
        self.thrtysecButton.clicked.connect(partial(self.plot, 30))
        self.twoMinButton = QtGui.QPushButton("2 Min")
        self.twoMinButton.clicked.connect(partial(self.plot, 120))
        self.fiveMinButton = QtGui.QPushButton("5 Min")
        self.fiveMinButton.clicked.connect(partial(self.plot, 300))
        self.thrtyMinButton = QtGui.QPushButton("30 Min")
        self.thrtyMinButton.clicked.connect(partial(self.plot, 1800))
        self.twoHrButton = QtGui.QPushButton("2 Hr")
        self.twoHrButton.clicked.connect(partial(self.plot, 7200))
        self.tenHrButton = QtGui.QPushButton("10 Hr")
        self.tenHrButton.clicked.connect(partial(self.plot, 36000))
        self.oneDayButton = QtGui.QPushButton("24 Hr")
        self.oneDayButton.clicked.connect(partial(self.plot, 86400))
        self.oneWkButton = QtGui.QPushButton("1 Wk")
        self.oneWkButton.clicked.connect(partial(self.plot, 604800))
        self.twoWkButton = QtGui.QPushButton("2 Wk")
        self.twoWkButton.clicked.connect(partial(self.plot, 1209600))
        self.allButton = QtGui.QPushButton("All Time")
        self.allButton.clicked.connect(partial(self.plot, None))
        self.canvas.hide()
        self.toolbar.hide()

        # set the layout

        buttonLayout = QtGui.QHBoxLayout()
        buttonLayout.addWidget(self.hideButton)
        buttonLayout.addStretch(0)
        buttonLayout2 = QtGui.QHBoxLayout()

        buttonLayout3 = QtGui.QHBoxLayout()

        buttonLayout2.addWidget(self.thrtysecButton)
        buttonLayout2.addWidget(self.twoMinButton)
        buttonLayout2.addWidget(self.fiveMinButton)
        buttonLayout2.addWidget(self.thrtyMinButton)
        buttonLayout2.addWidget(self.twoHrButton)
        buttonLayout2.addStretch(0)
        buttonLayout3.addWidget(self.tenHrButton)
        buttonLayout3.addWidget(self.oneDayButton)
        buttonLayout3.addWidget(self.oneWkButton)
        buttonLayout3.addWidget(self.twoWkButton)
        buttonLayout3.addWidget(self.allButton)
        buttonLayout3.addStretch(0)
        self.thrtysecButton.hide()
        self.twoMinButton.hide()
        self.fiveMinButton.hide()
        self.thrtyMinButton.hide()
        self.twoHrButton.hide()
        self.tenHrButton.hide()
        self.oneDayButton.hide()
        self.oneWkButton.hide()
        self.twoWkButton.hide()
        self.allButton.hide()
        self.matframe.hide()
        self.matPlotInfo.hide()
        self.toolbarFrame.hide()

        layout = QtGui.QVBoxLayout()
        layout.addLayout(buttonLayout)
        layout.addLayout(buttonLayout2)
        layout.addLayout(buttonLayout3)
        layout.addWidget(self.matPlotInfo)
        layout.addWidget(self.matframe)
        layout.addWidget(self.toolbarFrame)

        self.setLayout(layout)

    def enableAutoScaling(self):
        self.timer.start(self.refreshRateSec * 1000)
        # self.canvas.mpl_disconnect(self.cid)
        # self.cid = self.canvas.mpl_connect('button_press_event', self.disableAutoScaling)
        self.home = True
        self.matPlotInfo.hide()
        # self.deviceThread = threading.Thread(target =
        # self.plot, args=[self.currTimeRange])
        # If the main thread stops, stop the child thread
        # self.deviceThread.daemon = True
        # Start the thread
        # self.deviceThread.start()

        self.plot(self.currTimeRange)

    def disableAutoScaling(self, event):
        self.home = False
        self.matPlotInfo.show()
        self.canvas.update()
        # plt.show()
        # print event.name
        # self.canvas.mpl_disconnect(self.cid)
        # self.cid = self.canvas.mpl_connect('button_press_event', self.enableAutoScaling)
        self.timer.stop()
        # self.zoom(self.toolbar)

    def togglePlot(self):

        if not self.hidden:
            self.canvas.hide()
            self.toolbar.hide()
            self.thrtysecButton.hide()
            self.twoMinButton.hide()
            self.fiveMinButton.hide()
            self.thrtyMinButton.hide()
            self.twoHrButton.hide()
            self.tenHrButton.hide()
            self.oneDayButton.hide()
            self.oneWkButton.hide()
            self.twoWkButton.hide()
            self.allButton.hide()
            self.matPlotInfo.hide()
            self.matframe.hide()
            self.toolbarFrame.hide()
            self.timer.stop()
            self.hideButton.setText("Show Plot")
            self.hidden = True

        elif self.hidden:
            self.canvas.show()
            self.toolbar.show()
            self.thrtysecButton.show()
            self.twoMinButton.show()
            self.fiveMinButton.show()
            self.thrtyMinButton.show()
            self.twoHrButton.show()
            self.tenHrButton.show()
            self.oneDayButton.show()
            self.oneWkButton.show()
            self.twoWkButton.show()
            self.allButton.show()
            self.plot(self.currTimeRange)
            self.matframe.show()
            self.toolbarFrame.show()
            self.timer.start(self.refreshRateSec * 1000)
            self.hideButton.setText("Hide Plot")
            self.enableAutoScaling()
            self.hidden = False

    def plot(self, timeRange):
        if not self.hidden:
            if timeRange != self.currTimeRange:
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            if self.refreshRateSec != self.device.getFrame().getPlotRefreshRate():
                # print "New plot refresh rate: ", self.device.getFrame().getPlotRefreshRate()
                self.refreshRateSec = self.device.getFrame().getPlotRefreshRate()
                self.timer.stop()
                self.timer.timeout.disconnect()
                self.currTimeRange = timeRange
                self.timer.timeout.connect(lambda: self.plot(self.currTimeRange))
                self.timer.start(self.refreshRateSec * 1000)
            dataSet = self.device.getFrame().getDataSet()
            # If the dataset exists
            if dataSet is not None:
                # Get all data from the dataset
                data = dataSet.getData()
                self.ax.hold(False)
                try:
                    # for each entry in the dataset [[time], [[data], [data], [data...]]]
                    # print data
                    # Get the corresponding times that the values were recorded

                    for i in range(1, len(data[-1])):
                        # Get colum. aka all values from parameter i over time
                        column = [row[i] for row in data]

                        # print times
                        # If the there is  no defined a time range
                        if self.currTimeRange is None:
                            times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                            # Plot all of the data (columns) vs time
                            # self.ax.plot_date(times, column, label =
                            # dataSet.getVariables()[1][i-1][0])
                            pass
                        else:
                            # Otherwise, if the user PREVIOUSLY defined a time range,
                            # we need to look for the beginning of it.
                            # Start by getting the current time
                            dstamp = dateStamp()
                            # The dataset should be from now to -timerange
                            # time(now)-time(range)
                            startTime = dstamp.utcNowFloat() - self.currTimeRange
                            # If timeRange is not None, then we know we need
                            # to display only a certain range of values
                            # However, if the starttime defined is less than the lowest time, we
                            # do not have enough data to display the whole thing, so we must
                            # display all that we have instead. We do this by setting
                            # currTimeRange = 0.
                            if timeRange is not None and startTime < float(data[0][0]):
                                self.currTimeRange = None
                            # For all entries in data
                            for y in range(len(data)):
                                # We are searching backwards through the dataset to find a time
                                # just before the time range specified
                                if data[len(data) - y - 1][0] < startTime:
                                    # once we find it, we know the beginning index of the data to be
                                    # displayed
                                    index = y
                                    # Get the times and datafrom the index and columns to the end of the dataset
                                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data[-index:]]
                                    # print times[0]
                                    column = [row[i] for row in data[-index:]]
                                    # Exit the loop
                                    break

                        try:
                            while len(self.line) <= i:
                                self.line.append(self.ax.plot(1, 1, label=dataSet.getVariables()[1][i - 1][0])[0])

                            self.line[i].set_data(times, column)
                            self.ax.legend(loc="upper left", shadow=True, fancybox=True)
                            # maxi = max(column)
                            # mini = min(column)
                            # newMax = max(column)
                            # newMini = min(column)
                            # if(newMax>maxi)
                            # maxi=newMax
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # if(newMini<mini)
                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # maxi = max(column)
                            # mini = min(column)

                            # self.ax.set_ylim(mini-mini/2, maxi+maxi/2)
                            # self.ax.set_xlim(min(times), max(times))
                            # self.ax.draw_artist(self.line[i])
                        except:

                            traceback.print_exc()

                            # print "Failed to log data"
                        # Add a legend
                        legend = self.ax.legend(loc="upper left")
                        self.ax.set_title(
                            self.device.getFrame().getTitle(), color=(189.0 / 255, 195.0 / 255, 199.0 / 255)
                        )

                        if (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getCustomUnits()) is not 0
                        ):
                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getCustomUnits()
                                + ")"
                            )
                        elif (
                            self.device.getFrame().getYLabel() is not None
                            and len(self.device.getFrame().getUnits()[i - 1]) is not 0
                        ):

                            self.ax.set_ylabel(
                                self.device.getFrame().getYLabel()
                                + " ("
                                + self.device.getFrame().getUnits()[i - 1]
                                + ")"
                            )

                        self.ax.set_xlabel("Time")

                        self.ax.hold(True)
                        # locator = AutoDateLocator()
                        # self.ax.fmt_xdata = AutoDateFormatter()
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_locator(locator)
                        # self.ax.xaxis.set_major_formatter(DateFormatter('%m/%d'))

                        # self.ax.fmt_xdata = mdates.DateFormatter('%m/%d %H:%M:%S')
                        # print "type: ", type(times[-1])
                        # print "time[-1]: ",times[-1]
                        # self.ax.set_ylim(bottom = 733681, top = 733682)

                        # self.figure.tight_layout()
                        self.ax.grid(True)

                except Exception as e:
                    print "Error"
                try:

                    self.ax.grid(True)
                    # self.ax.clear(self.ax.yaxis)
                    # self.ax.cla()

                    if self.home:
                        self.ax.set_xlim(times[0], times[-1])
                        self.ax.relim()
                        self.ax.autoscale()

                    # print self.ax.get_data_interval()
                    self.ax.draw_artist(self.figure)
                    self.ax.draw_artist(self.ax.patch)

                    locator = AutoDateLocator()

                    self.ax.xaxis.set_major_locator(locator)
                    self.ax.xaxis.set_major_formatter(DateFormatter("%m/%d %H:%M:%S"))
                    self.figure.autofmt_xdate()
                    # print [time.toordinal() for time in times]
                    self.ax.draw_artist(self.ax.yaxis)
                    self.ax.draw_artist(self.ax.xaxis)

                    for line in self.line:
                        self.ax.draw_artist(line)

                    # self.ax.axis('off')

                    self.ax.draw_artist(legend)

                    self.canvas.update()

                    self.canvas.flush_events()

                except:
                    times = [datetime.datetime.fromtimestamp(row[0]) for row in data]
                    traceback.print_exc()
                    self.ax.set_xlim(times[0], times[-1])
                    self.ax.relim()
                    self.ax.autoscale()
                    # print self.ax.get_data_interval()
                    pass
Exemplo n.º 7
0
class TimeWaveform(QDialog):
    def __init__(self, parent=None):
        super(TimeWaveform, self).__init__(parent)
        self.x = None
        self.y1 = None
        self.y2 = None
        self.y3 = None
        self.y4 = None
        self.showType = "realtime"
        self.showTypeBtn = None

        # added push button
        self.showTypeBtn = QPushButton(u"realtiime", self)
        self.showTypeBtn.setFlat(True)
        self.showTypeBtn.setStyleSheet('QPushButton {font: bold 20px;}')
        self.showTypeBtn.clicked.connect(self.showTypeBtnClicked)
        buttonWidget = QWidget(self)
        layout2 = QHBoxLayout(buttonWidget)
        layout2.setAlignment(Qt.AlignHCenter)
        layout2.setContentsMargins(0, 0, 0, 0)
        layout2.setSpacing(10)
        layout2.addWidget(self.showTypeBtn)
        layout = QVBoxLayout()
        layout.addWidget(buttonWidget)

        self.setWindowFlags(Qt.WindowCloseButtonHint |
                            Qt.WindowMinimizeButtonHint |
                            Qt.WindowMaximizeButtonHint |
                            Qt.Dialog)
        self.setWindowTitle(u"tool ")
        self.mainLayout = QHBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.splitter = QSplitter(self)
        self.splitterLayout = QHBoxLayout(self.splitter)
        self.treeView = QTreeView(self)
        self.model = QStandardItemModel(self)
        self.treeView.setModel(self.model)
        self.treeView.setHeaderHidden(True)

        custom = ["yk001", "yk002", "yk003"]
        for cm in custom:
            custom = QStandardItem(cm)
            custom.setToolTip(cm)
            fnames = database.getTableName(cm)
            print "fnames == ", fnames
            for f in fnames:
                ff = QStandardItem(f)
                ff.setToolTip(f)
                custom.appendRow(ff)
                ff.setData({'custom_name': cm, 'datetime_data': f}, Qt.UserRole)
            self.model.appendRow(custom)

        self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.splitterLayout.addWidget(self.treeView)
        self.treeView.header().setResizeMode(QHeaderView.ResizeToContents)

        self.frame = QWidget(self)
        self.frameLayout = QVBoxLayout(self.frame)
        self.splitterLayout.addWidget(self.frame)
        self.mainLayout.addWidget(self.splitter)
        self.splitter.setSizes([20, 400])
        self.figure = Figure(figsize=(400, 400), dpi=72, facecolor=('none'), edgecolor=('none'), frameon=False)
        self.figure.subplots_adjust(hspace=0.2)

        self.ax = self.figure.add_subplot(412)

        self.ax2 = self.figure.add_subplot(413, sharex=self.ax, sharey=self.ax)

        self.ax3 = self.figure.add_subplot(414, sharex=self.ax, sharey=self.ax)

        self.ax4 = self.figure.add_subplot(411, sharex=self.ax)

        self.canvas = FigureCanvas(self.figure)
        self.treeView.doubleClicked.connect(self.showChart)
        self.toolBar = NavigationToolbar(self.canvas, self)
        self.frameLayout.addWidget(self.toolBar)
        self.frameLayout.addWidget(buttonWidget)
        self.frameLayout.addWidget(self.canvas)

        # load multi thread
        self.loadRealTimeThread = LoadRealTimeThread(waveform=self, parent=self)
        self.loadRealTimeThread.finished.connect(self.onFinished)

        self.loadBrakeAmplitudeThread = LoadBrakeAmplitudeThread(waveform=self, parent=self)
        self.loadBrakeAmplitudeThread.finished.connect(self.onFinished)

    def onFinished(self):
        self.ax.clear()
        self.ax2.clear()
        self.ax3.clear()
        self.ax4.clear()
        self.plots()
        self.canvas.draw()

    def showChart(self, s):
        self.showType = "realtime"
        self.showTypeBtn.setText(u"rl")
        data_tree = s.data(Qt.UserRole)
        if not data_tree:
            return
        sharemem.Set('data_tree', data_tree)
        self.loadRealTimeThread.start()
        self.showLoading()

    def plots(self):
        self.ax.plot(self.x, self.y1, label='max_c1', linestyle='solid', color='orange', linewidth=0.5)
        self.ax.set_ylabel(u"Amp")
        self.ax.set_ylim(np.min([self.y1.min(), self.y2.min(), self.y3.min()]) - 1,
                                np.max([self.y1.max(), self.y2.max(), self.y3.max()]) + 3)
        self.ax.legend()

        self.ax2.plot(self.x, self.y2, label='max_c2', linestyle='solid', color='green', linewidth=0.5)
        self.ax2.set_ylabel(u"Amp")
        self.ax2.legend()

        self.ax3.plot(self.x, self.y3, label='max_c3', linestyle='solid', color='red', linewidth=0.5)
        self.ax3.set_xlabel(u"Time")
        self.ax3.set_ylabel(u"Amp")
        self.ax3.legend()

        self.ax4.plot(self.x, self.y4, label='speed', linestyle='solid', color='blue', linewidth=0.5)
        self.ax4.set_title((str(self.x[0]))[:-3] + "~" + (str(self.x[-1]))[:-3])
        self.ax4.set_ylabel(u"Speed")
        self.ax4.legend()

    def onClicked(self):
        if self.showType == "realtime":
            self.loadRealTimeThread.start()
            self.showLoading()
        elif self.showType == "brake":
            self.loadBrakeAmplitudeThread.start()
            self.showLoading()

    def showTypeBtnClicked(self):
        if self.showType == "realtime":
            self.showType = "brake"
            self.showTypeBtn.setText(u"br")
            self.onClicked()
        elif self.showType == "brake":
            self.showType = "realtime"
            self.showTypeBtn.setText(u"rl")
            self.onClicked()

    def showLoading(self):
        self.ax.clear()
        self.ax2.clear()
        self.ax3.clear()
        self.ax4.clear()
        self.ax4.set_title("Loading...")
        self.canvas.update()
Exemplo n.º 8
0
class Window(QMainWindow, Ui_MainWindow):
    def __init__(self, parent = None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)

#defines thread get_temp
        self.get_temp = Get_Temp()
#defines thread get_data
        self.get_data = Get_Data()
#defines timer
        self.timer = QtCore.QTimer(self)
#signal to start threads
        self.connect(self.get_temp, SIGNAL("display_temp()"),self.display_temp,Qt.DirectConnection)
        self.connect(self.get_data, SIGNAL("plot()"),self.plot,Qt.DirectConnection)
#defines a graph and plots it in vertical layout
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.verticalLayout.addWidget(self.canvas)        
#starts get_temp thread
        self.get_temp.start()
#starts timer
        self.timer.timeout.connect(self.Time)
#HLT timer button signal
        self.HTL_Start.clicked.connect(self.Set)
#defines and starts timer2
        self.timer2 = QtCore.QTimer(self)
        self.timer2.timeout.connect(self.Time2)
#Boil timer button signal
        self.BOIL_TIMER_START_2.clicked.connect(self.Set2)
#defines and starts timer3        
        self.timer3 = QtCore.QTimer(self)
        self.timer3.timeout.connect(self.Time3)
#signals for graph timmer buttons
        self.START_TIMER.clicked.connect(self.Start)
        self.STOP_TIMER.clicked.connect(lambda: self.timer3.stop())
        self.RESET_TIMER.clicked.connect(self.Reset)
        self.ALARM_RESET.clicked.connect(self.Alarm_Reset)
#dictionaries for alarm values
        global alarm1,alarm2
        alarm1 = {self.HLT_alarm_set1:self.ALARM_HLT_1,self.HLT_alarm_set1_2:self.ALARM_HLT_2,self.HLT_alarm_set1_3:self.ALARM_HLT_3,self.HLT_alarm_set1_4:self.ALARM_HLT_4,self.HLT_alarm_set1_5:self.ALARM_HLT_5}
        alarm2 = {self.Boil_alarm_set1:self.ALARM_BOIL_1,self.Boil_alarm_set1_2:self.ALARM_BOIL_2,self.Boil_alarm_set1_3:self.ALARM_BOIL_3,self.Boil_alarm_set1_4:self.ALARM_BOIL_4,self.Boil_alarm_set1_5:self.ALARM_BOIL_5}    
#signals for file dropdown buttons
        self.actionQuit.triggered.connect(self.close_application)
        self.actionSave.triggered.connect(self.save_application)
        self.actionLoad.triggered.connect(self.load_application)
        self.actionNew.triggered.connect(self.reset_data)

#closes the application       
    def close_application(self):
        print("window close")
        sys.exit()
        
#gets data from form and saves it to a file
    def save_application(self):
        self.save_data()
        text2 = []
        name = QtGui.QFileDialog.getSaveFileName()
        file = open(name,'w')        
        for i in self.form_field:
            file.write(i + "\n")
        file.close()
        file = ""
        self.form_field = []
        print ("saved")
        
#Gets data from a file and send it to get_data
    def load_application(self):
        self.reset_data()
        temp=[]
        name = QtGui.QFileDialog.getOpenFileName()
        file = open(name,'r')
        for i in file:
            temp1 = i[:-1]
            temp.append(temp1)
        file.close()
        file = ""
            
        self.load_data(temp)    
        print ("loaded")
        
#Gets data from Receipe form
    def save_data(self):
        self.form_field = [self.Brewer_name_txt.text(),
        self.Brew_Date_txt.text(),
        self.Batch_size_txt.text(),
        self.boil_time_txt.text(),
        self.Ingredient_one.text(),
        self.Amount_one.text(),
        self.Ingredient_three.text(),
        self.Amount_three.text(),
        self.Ingredient_two.text(),
        self.Amount_two.text(),
        self.Ingredient_four.text(),
        self.Alcohol_volume_txt.text(),
        self.Amount_four.text(),
        self.Ingredient_five.text(),
        self.Amount_five.text(),
        self.Hop_one.text(),
        self.hop_amount_one.text(),
        self.hop_AA_one.text(),
        self.hop_boil_one.text(),
        self.hop_amount_two.text(),
        self.hop_boil_two.text(),
        self.hop_AA_two.text(),
        self.hop_two.text(),
        self.hop_amount_three.text(),
        self.hop_boil_three.text(),
        self.hop_AA_three.text(),
        self.hop_3.text(),
        self.hop_amount_four.text(),
        self.hop_boil_four.text(),
        self.hop_AA_four.text(),
        self.hop_4.text(),
        self.hop_amount_five.text(),
        self.hop_boil_five.text(),
        self.hop_AA_five.text(),
        self.hop_five.text(),
        self.original_gravity_txt.text(),
        self.final_gravity_txt.text(),
        self.IBU_txt.text(),
        self.SRM_txt.text(),
        self.Brewhouse_efficiency_txt.text(),
        self.Carbonation_level_txt.text(),
        self.hydrometer_preboil_date_txt.text(),
        self.hydrometer_afterboil_date_txt.text(),
        self.hydrometer_racked_date_txt.text(),
        self.hydrometer_final_date_txt.text(),
        self.hydrometer_preboil_gravity_txt.text(),
        self.hydrometer_racked_gravity_txt.text(),
        self.hydrometer_final_gravity_txt.text(),
        self.hydrometer_afterboil_gravity_txt.text(),        
        self.Recipe_name_txt.text(),
        self.beer_type_txt.text(),
        self.Batch_txt.text(),
        self.efficiency_txt.text(),
        self.infusion_one_txt.text(),
        self.infusion_temp_one_txt.text(),
        self.infusion_three_txt.text(),
        self.infusion_temp_three_txt.text(),
        self.infusion_two_txt.text(),
        self.infusion_temp_two_txt.text(),
        self.infusion_four_txt.text(),
        self.infusion_temp_four_txt.text(),
        self.infusion_five_txt.text(),
        self.infusion_temp_five_txt.text(),
        self.cost_grains_txt.text(),
        self.cost_grains_txt_2.text(),
        self.cost_yeast_txt.text(),
        self.cost_other_txt.text(),
        self.infusion_time_one_txt.text(),
        self.infusion_time_four_txt.text(),
        self.infusion_time_five_txt.text(),
        self.infusion_time_two_txt.text(),
        self.infusion_time_three_txt.text(),
        self.yeat_starter_txt.text(),
        self.yeast_attenuation_txt.text(),        
        self.yeast_type_txt.text(),       
        self.cost_total_txt.text(),
        self.Notes.toPlainText()]
        
#fills the recipe form with data from a file            
    def load_data(self,x):
        
        self.Brewer_name_txt.setText(x[0])
        self.Brew_Date_txt.setText(x[1])
        self.Batch_size_txt.setText(x[2])
        self.boil_time_txt.setText(x[3])
        self.Ingredient_one.setText(x[4])
        self.Amount_one.setText(x[5])
        self.Ingredient_three.setText(x[6])
        self.Amount_three.setText(x[7])
        self.Ingredient_two.setText(x[8])
        self.Amount_two.setText(x[9])
        self.Ingredient_four.setText(x[10])
        self.Alcohol_volume_txt.setText(x[11])
        self.Amount_four.setText(x[12])
        self.Ingredient_five.setText(x[13])
        self.Amount_five.setText(x[14])
        self.Hop_one.setText(x[15])
        self.hop_amount_one.setText(x[16])
        self.hop_AA_one.setText(x[17])
        self.hop_boil_one.setText(x[18])
        self.hop_amount_two.setText(x[19])
        self.hop_boil_two.setText(x[20])
        self.hop_AA_two.setText(x[21])
        self.hop_two.setText(x[22])
        self.hop_amount_three.setText(x[23])
        self.hop_boil_three.setText(x[24])
        self.hop_AA_three.setText(x[25])
        self.hop_3.setText(x[26])
        self.hop_amount_four.setText(x[27])
        self.hop_boil_four.setText(x[28])
        self.hop_AA_four.setText(x[29])
        self.hop_4.setText(x[30])
        self.hop_amount_five.setText(x[31])
        self.hop_boil_five.setText(x[32])
        self.hop_AA_five.setText(x[33])
        self.hop_five.setText(x[34])
        self.original_gravity_txt.setText(x[35])
        self.final_gravity_txt.setText(x[36])
        self.IBU_txt.setText(x[37])
        self.SRM_txt.setText(x[38])
        self.Brewhouse_efficiency_txt.setText(x[39])
        self.Carbonation_level_txt.setText(x[40])
        self.hydrometer_preboil_date_txt.setText(x[41])
        self.hydrometer_afterboil_date_txt.setText(x[42])
        self.hydrometer_racked_date_txt.setText(x[43])
        self.hydrometer_final_date_txt.setText(x[44])
        self.hydrometer_preboil_gravity_txt.setText(x[45])
        self.hydrometer_racked_gravity_txt.setText(x[46])
        self.hydrometer_final_gravity_txt.setText(x[47])
        self.hydrometer_afterboil_gravity_txt.setText(x[48])        
        self.Recipe_name_txt.setText(x[49])
        self.beer_type_txt.setText(x[50])
        self.Batch_txt.setText(x[51])
        self.efficiency_txt.setText(x[52])
        self.infusion_one_txt.setText(x[53])
        self.infusion_temp_one_txt.setText(x[54])
        self.infusion_three_txt.setText(x[55])
        self.infusion_temp_three_txt.setText(x[56])
        self.infusion_two_txt.setText(x[57])
        self.infusion_temp_two_txt.setText(x[58])
        self.infusion_four_txt.setText(x[59])
        self.infusion_temp_four_txt.setText(x[60])
        self.infusion_five_txt.setText(x[61])
        self.infusion_temp_five_txt.setText(x[62])
        self.cost_grains_txt.setText(x[63])
        self.cost_grains_txt_2.setText(x[64])
        self.cost_yeast_txt.setText(x[65])
        self.cost_other_txt.setText(x[66])
        self.infusion_time_one_txt.setText(x[67])
        self.infusion_time_four_txt.setText(x[68])
        self.infusion_time_five_txt.setText(x[69])
        self.infusion_time_two_txt.setText(x[70])
        self.infusion_time_three_txt.setText(x[71])
        self.yeat_starter_txt.setText(x[72])
        self.yeast_attenuation_txt.setText(x[73])        
        self.yeast_type_txt.setText(x[74]) 
        self.cost_total_txt.setText(x[75])
        for i in range(76,len(x),1):
            temp = x[i]
            temp = temp[:-1]
            self.Notes.append(temp)
            
        

#fills recipe form with blank spaces
    def reset_data(self):
        x=" "
        self.Brewer_name_txt.setText(x)
        self.Brew_Date_txt.setText(x)
        self.Batch_size_txt.setText(x)
        self.boil_time_txt.setText(x)
        self.Ingredient_one.setText(x)
        self.Amount_one.setText(x)
        self.Ingredient_three.setText(x)
        self.Amount_three.setText(x)
        self.Ingredient_two.setText(x)
        self.Amount_two.setText(x)
        self.Ingredient_four.setText(x)
        self.Alcohol_volume_txt.setText(x)
        self.Amount_four.setText(x)
        self.Ingredient_five.setText(x)
        self.Amount_five.setText(x)
        self.Hop_one.setText(x)
        self.hop_amount_one.setText(x)
        self.hop_AA_one.setText(x)
        self.hop_boil_one.setText(x)
        self.hop_amount_two.setText(x)
        self.hop_boil_two.setText(x)
        self.hop_AA_two.setText(x)
        self.hop_two.setText(x)
        self.hop_amount_three.setText(x)
        self.hop_boil_three.setText(x)
        self.hop_AA_three.setText(x)
        self.hop_3.setText(x)
        self.hop_amount_four.setText(x)
        self.hop_boil_four.setText(x)
        self.hop_AA_four.setText(x)
        self.hop_4.setText(x)
        self.hop_amount_five.setText(x)
        self.hop_boil_five.setText(x)
        self.hop_AA_five.setText(x)
        self.hop_five.setText(x)
        self.original_gravity_txt.setText(x)
        self.final_gravity_txt.setText(x)
        self.IBU_txt.setText(x)
        self.SRM_txt.setText(x)
        self.Brewhouse_efficiency_txt.setText(x)
        self.Carbonation_level_txt.setText(x)
        self.hydrometer_preboil_date_txt.setText(x)
        self.hydrometer_afterboil_date_txt.setText(x)
        self.hydrometer_racked_date_txt.setText(x)
        self.hydrometer_final_date_txt.setText(x)
        self.hydrometer_preboil_gravity_txt.setText(x)
        self.hydrometer_racked_gravity_txt.setText(x)
        self.hydrometer_final_gravity_txt.setText(x)
        self.hydrometer_afterboil_gravity_txt.setText(x)
        self.Recipe_name_txt.setText(x)
        self.beer_type_txt.setText(x)
        self.Batch_txt.setText(x)
        self.efficiency_txt.setText(x)
        self.infusion_one_txt.setText(x)
        self.infusion_temp_one_txt.setText(x)
        self.infusion_three_txt.setText(x)
        self.infusion_temp_three_txt.setText(x)
        self.infusion_two_txt.setText(x)
        self.infusion_temp_two_txt.setText(x)
        self.infusion_four_txt.setText(x)
        self.infusion_temp_four_txt.setText(x)
        self.infusion_five_txt.setText(x)
        self.infusion_temp_five_txt.setText(x)
        self.cost_grains_txt.setText(x)
        self.cost_grains_txt_2.setText(x)
        self.cost_yeast_txt.setText(x)
        self.cost_other_txt.setText(x)
        self.infusion_time_one_txt.setText(x)
        self.infusion_time_four_txt.setText(x)
        self.infusion_time_five_txt.setText(x)
        self.infusion_time_two_txt.setText(x)
        self.infusion_time_three_txt.setText(x)
        self.yeat_starter_txt.setText(x)
        self.yeast_attenuation_txt.setText(x)
        self.yeast_type_txt.setText(x) 
        self.cost_total_txt.setText(x)
        self.Notes.setText(x)

#resets the alarm and sets gpio 18 to low        
    def Alarm_Reset(self):
        os.system('sh -c "echo low > /sys/class/gpio/gpio18/direction"')
                       

       
                    
#Resets timmer for graph
    def Reset(self):
        global s3,m3,h3
        self.timer3.stop()        
        s3=0
        m3=0
        h3=0
        self.get_data.start()
        time = "{0}:{1}:{2}".format(h3,m3,s3)
        self.TIMER_DISPLAY.setDigitCount(len(time))
        self.TIMER_DISPLAY.display(time)

#starts timer for graph
    def Start(self):
        global s3,m3,h3
        self.timer3.start(1000)
        
#Timer for graph and displays time (counts up)   
    def Time3(self):
        global s3,m3,h3           
        
        if s3 == 0:
            self.get_data.start()
           
        if s3 == 30:
            self.get_data.start()
            
        if s3<59:
            s3 += 1
        else:
            if m3 < 59:
                s3 = 0
                m3 += 1
            elif m3 == 59 and h3 < 24:
                h3 += 1
                m3 = 0
                s3= 0
            else:
                self.timer3.stop()
        time = "{0}:{1}:{2}".format(h3,m3,s3)

        self.TIMER_DISPLAY.setDigitCount(len(time))
        self.TIMER_DISPLAY.display(time)
        
#Sets HLT timer
    def Set(self):
        global t,h,m,s
        t = self.HLT_TIMER_SET.time()
        self.HLT_Timer_DISPLAY.display(t.toString())
        self.timer.start(1000)
        
        h = t.hour()
        m = t.minute()
        s = t.second()
        
        
#Timer for HLT timer(counts the timer down)    
    def Time(self):
        global t,h,m,s,time1
        
        
        if s > 0:
            s -= 1
        else:
            if m > 0:
                m -= 1
                s = 59
            elif m == 0 and h > 0:
                h -= 1
                m = 59
                s = 59
            else:
                self.timer.stop()
        time1 = ("{0}:{1}:{2}".format(h,m,s))
        self.Alarm()
        self.HLT_Timer_DISPLAY.setDigitCount(len(time1))
        self.HLT_Timer_DISPLAY.display(time1)
        
#Sets boil timer        
    def Set2(self):
        global t2,h2,m2,s2
        t2 = self.BOIL_TIMER_SET.time()
        self.BOIL_TIMER_DISPLAY.display(t2.toString())
        self.timer2.start(1000)
        
        h2 = t2.hour()
        m2 = t2.minute()
        s2 = t2.second()
        
        
#timer for boil timer(counts the timer down)    
    def Time2(self):
        global t2,h2,m2,s2,time2
        
        
        if s2 > 0:
            s2 -= 1
        else:
            if m2 > 0:
                m2 -= 1
                s2 = 59
            elif m2 == 0 and h2 > 0:
                h2 -= 1
                m2 = 59
                s2 = 59
            else:
                self.timer2.stop()
        time2 = ("{0}:{1}:{2}".format(h2,m2,s2))
        self.Alarm()
        self.BOIL_TIMER_DISPLAY.setDigitCount(len(time2))
        self.BOIL_TIMER_DISPLAY.display(time2)
        
#checks to see if alarm has been triggered and sets gpio 18 to high
    def Alarm(self):
        global alarm1,alarm2,time1,time2
        
        for x, y in alarm1.iteritems():
            
            if x.isChecked():
                a = y.time()
                h = a.hour()
                m = a.minute()
                s = a.second()
                
                time4 = ("{0}:{1}:{2}".format(h,m,s))
                if time4 == time1:
                     print "ALARM 1 ACTIVE"
                     os.system('sh -c "echo low > /sys/class/gpio/gpio18/direction"')
                     
                        
        for x, y in alarm2.iteritems():
            if x.isChecked():
                a = y.time()
                h = a.hour()
                m = a.minute()
                s = a.second()
                
                time4 = ("{0}:{1}:{2}".format(h,m,s))
                if time4 == time2:
                     print "ALARM 2 ACTIVE"
                     os.system('sh -c "echo high > /sys/class/gpio/gpio18/direction"')        






#displays temps by calling settemp from temprature.py 
    def display_temp(self):
            temp = sent_temp()
            self.HLT_TEMP.display(temp[0])
            self.MASH_TEMP.display(temp[1])
            self.Boil_TEMP.display(temp[2])
            
#creates a graph and displays it
    def plot(self):
        temp = sent_temp()
        temp1.append(temp[0])
        temp2.append(temp[1])
        temp3.append(temp[2])
        M1.append(m3)        
        XHLT= self.figure.add_subplot(111)             
        XHLT.plot(M1,temp1,'b-',label = "HLT")
        XHLT.plot(M1,temp2,'r-',label = "MASH")
        XHLT.plot(M1,temp3,'g-',label = "BOIL")
        self.canvas.draw()
        self.canvas.update()
        if m3 == 0 and h3 == 0 and s3 == 0:
            XHLT.hold(False)
Exemplo n.º 9
0
 def update(self):
     self.fig.tight_layout()
     FigureCanvas.update(self)
Exemplo n.º 10
0
 def update(self):
     self.fig.tight_layout()
     FigureCanvas.update(self)
Exemplo n.º 11
0
class Window(QtWidgets.QDialog):
    ## Class to create animation object that plots real-time voltage vs time

    def __init__(self, channel, fs, N_samples):
        super(Window, self).__init__()
        self.channel = channel
        self.fs = fs
        self.N_samples = N_samples

        ## Animation figure
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)

        ## Animate button
        self.button = QtWidgets.QPushButton('Animate')
        self.button.clicked.connect(self.animate)

        ## Set the layout
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def animate(self):
        ## Animation figure settings
        self.ax = self.fig.add_subplot(111)
        self.line, = self.ax.plot([], [], lw=1)
        self.ax.grid()
        self.ax.set_ylim(-5, 5)
        self.ax.set_xlim(0, 10)
        self.ax.set_xlabel('Time [sec]')
        self.ax.set_ylabel('Voltage Out [V]')
        self.ax.set_title('Channel ' + str(self.channel))
        self.xdata, self.ydata = [], []

        def data_gen(t=0):
            ## Generate real-time time and voltage for each frame
            run = Measurement(
                fs=self.fs,
                active_channels=[0, 1])  ## Instance of measurement class
            cnt = 0
            while cnt < self.N_samples:
                cnt = cnt + 1
                data_loop(run)  ## Adds point to end of vtime and data list
                yield run.time[-1], run.data[-1][self.channel]

        ## ~Run animation functioion~
        self.anim = animation.FuncAnimation(self.fig,
                                            self.animate_loop,
                                            data_gen,
                                            blit=True,
                                            interval=.001,
                                            repeat=False,
                                            init_func=self.initial)
        ## Update figure in GUI
        self.canvas.update()

    def initial(self):
        ## Clear data
        self.line.set_data([], [])

        return self.line,

    def animate_loop(self, data):
        ## Update data
        t, y = data
        self.xdata.append(t)
        self.ydata.append(y)
        xmin, xmax = self.ax.get_xlim()
        ymin, ymax = self.ax.get_ylim()

        ## Adjust plot boundaries accordingly
        if t >= xmax:
            self.ax.set_xlim(xmin, 2 * xmax)
            self.ax.figure.canvas.draw()
        if y >= ymax:
            self.ax.set_ylim(ymin, 2 * ymax)
            self.ax.figure.canvas.draw()
        if ymin < 0:  ## Make sure ymin limit is negative if this is used
            if y <= ymin:
                self.ax.set_ylim(2 * ymin, ymax)
                self.ax.figure.canvas.draw()
        self.line.set_data(self.xdata, self.ydata)

        return self.line,
Exemplo n.º 12
0
class InteractiveVelocityPlot(VelocityPlot):
    """
    Visual tool to help with fitting Voigt profiles to absorption lines
    in QSO spectra.

    """

    def __init__(self, filename, transitions, wavelength, flux, error,
                 continuum, redshift, **kwargs):

        # Main window:
        self.window = QMainWindow()

        # Host widget for plot, push button, and checkboxes:
        self.main_frame = QWidget()

        # Spectrum filename:
        self.filename = filename

        # Plotting options:
        self.options = kwargs

        # Optimise screen usage:
        if len(transitions) > 20:
            ncols = int(ceil(len(transitions) / 10))
        else:
            ncols = int(ceil(len(transitions) / 5))

        # Initialise plot:
        super(InteractiveVelocityPlot, self).__init__(
            transitions, ncols=ncols, aspect=0.45, **self.options['WINDOW'])

        # Attach canvas to host widget:
        self.canvas = FigureCanvasQTAgg(self)
        self.canvas.setParent(self.main_frame)

        # Text input/output:
        self.text_output = QTextEdit()

        # Push buttons:
        self.load_button = QPushButton('&Load')
        self.save_button = QPushButton('&Save')
        self.preview_button = QPushButton('&Preview')
        self.clear_button = QPushButton('&Clear')
        self.refresh_plot_button = QPushButton('&Refresh plot')
        self.plot_model_button = QPushButton('&Plot model')
        self.plot_all_models_button = QPushButton('&Plot all models')
        self.clear_models_button = QPushButton('&Clear models')
        self.runvpfit_button = QPushButton('&Run VPFIT')
        self.set_resolution = QPushButton('&Set resolution')
        self.help = QPushButton('&Help')
        self.quit = QPushButton('&Quit')

        # Checkboxes:
        self.cos_fuv_checkbox = QCheckBox('&use COS FUV LSF')
        self.cos_nuv_checkbox = QCheckBox('&use COS NUV LSF')
        self.include_checkbox = QCheckBox('&include previous')

        # Push button `clicked` connections:
        self.load_button.clicked.connect(self.on_load)
        self.save_button.clicked.connect(self.on_save)
        self.preview_button.clicked.connect(self.on_preview)
        self.clear_button.clicked.connect(self.on_clear)
        self.refresh_plot_button.clicked.connect(self.on_refresh)
        self.plot_model_button.clicked.connect(self.on_plot_model)
        self.plot_all_models_button.clicked.connect(self.on_plot_all_models)
        self.clear_models_button.clicked.connect(self.on_clear_models)
        self.runvpfit_button.clicked.connect(self.on_runvpfit)
        self.set_resolution.clicked.connect(self.on_resolution)
        self.help.clicked.connect(self.on_help)
        self.quit.clicked.connect(self.window.close)

        # Checkbox `stateChanged` connections:
        self.cos_fuv_checkbox.stateChanged.connect(self.on_cos_fuv_checkbox)
        self.cos_nuv_checkbox.stateChanged.connect(self.on_cos_nuv_checkbox)
        self.include_checkbox.stateChanged.connect(self.on_include_checkbox)

        # Set up grid layout:
        grid = QGridLayout()
        grid.setSpacing(10)

        # Add widgets:
        grid.addWidget(self.text_output, 1, 1, 4, 3)
        grid.addWidget(self.load_button, 1, 4)
        grid.addWidget(self.save_button, 2, 4)
        grid.addWidget(self.preview_button, 3, 4)
        grid.addWidget(self.clear_button, 4, 4)
        grid.addWidget(self.refresh_plot_button, 1, 5)
        grid.addWidget(self.plot_model_button, 2, 5)
        grid.addWidget(self.plot_all_models_button, 3, 5)
        grid.addWidget(self.clear_models_button, 4, 5)
        grid.addWidget(self.runvpfit_button, 1, 6)
        grid.addWidget(self.cos_fuv_checkbox, 2, 6)
        grid.addWidget(self.cos_nuv_checkbox, 3, 6)
        grid.addWidget(self.include_checkbox, 4, 6)
        grid.addWidget(self.set_resolution, 1, 7)
        grid.addWidget(self.help, 3, 7)
        grid.addWidget(self.quit, 4, 7)

        # Place plotting canvas above the options grid:
        vbox = QVBoxLayout()
        vbox.addWidget(self.canvas)
        vbox.addLayout(grid)

        # Set the layout to the host widget:
        self.main_frame.setLayout(vbox)

        # Store all static elements (can be very slow to re-draw these):
        self.canvas.draw()
        self.backgrounds = [self.canvas.copy_from_bbox(ax.bbox)
                            for ax in self.axes]

        # Plot the data:
        self.plot_data(wavelength, flux, error, continuum, redshift,
                       **self.options['DATA'])

        # Set the window title:
        self.window.setWindowTitle('vpguess z = {0:.3f}'.format(self.redshift))

        # Give keyboard focus to the figure:
        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()

        # Variable defaults:
        self.cos_fuv = False
        self.cos_nuv = False
        self.include = False
        self.last_loaded = None
        self.resolution = None

        # Keypress variables:
        self.previous_keypress = None
        self.previous_wavelength = None

        # Set up the key-press events:
        self.canvas.mpl_connect('key_press_event', self.on_keypress)

        # Set the main frame as the central widget:
        self.window.setCentralWidget(self.main_frame)

        # Resize the window so it will display the canvas with the
        # requested size:
        layout_height = vbox.sizeHint().height()
        layout_width = vbox.sizeHint().width()
        status_bar_height = self.window.statusBar().sizeHint().height()
        height = layout_height + status_bar_height
        self.window.resize(layout_width, height)

        # Re-do labels:
        del self.texts[:]
        self.text(0.45, 0.02, 'Velocity offset (km s$^{-1}$)')
        self.text(0.01, 0.57, 'Transmission', rotation=90)

        # Disable any existing callbacks:
        self.cids = dict()
        cids1 = list(self.canvas.callbacks.callbacks['key_press_event'])
        cids2 = list(self.canvas.callbacks.callbacks['button_press_event'])
        cids = cids1 + cids2
        for cid in cids:
            self.canvas.callbacks.disconnect(cid)

        # Connect new callbacks:
        self.connect()

    def update_plot(self, redshift):

        # Restore background regions:
        [self.canvas.restore_region(background)
         for background in self.backgrounds]

        # Plot data:
        [data.pop(0).remove() for data in self.data]
        self.plot_data(
            self.wavelength, self.flux, self.error, self.continuum,
            redshift, **self.options['DATA'])

        # Draw the artists:
        for artists in self.data:
            for element in artists:
                ax = element.get_axes()
                ax.draw_artist(element)

        # Plot the models (if any):
        if self.options['MODEL']['absorbers'] is not None:
            self.plot_models(resolution=self.resolution,
                             convolve_with_cos_fuv=self.cos_fuv,
                             convolve_with_cos_nuv=self.cos_nuv,
                             **self.options['MODEL'])

            # Draw the artists:
            for artists in self.models:
                for element in artists:
                    ax = element.get_axes()
                    ax.draw_artist(element)

        # Draw new panel labels:
        for i, transition in enumerate(self.transitions):

            ax = self.axes[self._ind[i]]
            transf = blended_transform_factory(ax.transAxes, ax.transData)
            name = transition.name

            # Use TeX fonts if specified:
            if self.usetex:
                name = name.split()
                if name[0][1].islower():
                    name = name[0][:2] + '$\;$\\textsc{' + \
                        name[0][2:].lower() + '} $\lambda$' + name[1]
                else:
                    name = name[0][:1] + '$\;$\\textsc{' + \
                        name[0][1:].lower() + '} $\lambda$' + name[1]

            label = ax.text(0.03, 0.5, name, fontsize=self.label_fontsize,
                            bbox=bbox, transform=transf)
            ax.draw_artist(label)

        # Update:
        self.canvas.update()
        self.window.setWindowTitle(
            'vpguess z = {0:.3f}'.format(self.redshift))

    @staticmethod
    def concatenate_results():

        from glob import glob
        results = glob('*.result')

        with open('.all_results', 'wb') as combined:
            for result in results:
                with open(result, 'rb') as single:
                    combined.write(single.read())

    @pyqtSlot(str)
    def on_output(self, output):

        self.text_output.moveCursor(QTextCursor.End)
        self.text_output.insertPlainText(output)

    def on_load(self):

        self.text_output.clear()

        directory = os.getcwd()
        filename = QFileDialog.getOpenFileName(
            self.window, 'Select f26 file', directory)

        with open(filename, 'rb') as f26:
            self.text_output.setText(f26.read())

        self.last_loaded = filename

    def on_save(self):

        directory = os.getcwd()
        filename, ok = QFileDialog.getSaveFileName(
            self.window, 'Save f26 file', directory)

        with open(filename, 'w') as f26:
            f26.write(str(self.text_output.toPlainText()))

        self.text_output.clear()
        self.last_loaded = None

    def on_preview(self):

        self.concatenate_results()

        with open('.f26_preview', 'wb') as preview:
            with open('.all_results', 'rb') as results:
                preview.write(str(self.text_output.toPlainText()))
                preview.write(results.read())

        f26 = read_f26('.f26_preview')

        self.options['MODEL']['absorbers'] = f26.absorbers
        self.update_plot(self.redshift)

    def on_clear(self):

        self.text_output.clear()
        self.last_loaded = None

    def on_refresh(self):

        self.update_plot(self.redshift)

    def on_plot_model(self):

        directory = os.getcwd()
        filename = QFileDialog.getOpenFileName(
            self.window, 'Select f26 file', directory)

        f26 = read_f26(filename)
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

    def on_plot_all_models(self):

        self.concatenate_results()

        f26 = read_f26('.all_results')
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

    def on_clear_models(self):

        self.options['MODEL']['absorbers'] = None
        self.update_plot(self.redshift)

    def on_runvpfit(self):

        from .vpfit import run_vpfit

        directory = os.getcwd()

        if self.last_loaded is not None:

            filename = self.last_loaded

            if self.text_output.document().isModified():
                with open(filename, 'w') as f26:
                    f26.write(str(self.text_output.toPlainText()))

        else:

            filename = QFileDialog.getSaveFileName(
                self.window, 'Save f26 file', directory)

            with open(filename, 'w') as f26:
                f26.write(str(self.text_output.toPlainText()))

        self.concatenate_results()
        inc = '.all_results' if self.include else None

        self.text_output.clear()
        fwhm = self.resolution if self.resolution is not None else 10
        run_vpfit(filename, inc, fwhm=fwhm, cos_fuv=self.cos_fuv,
                  cos_nuv=self.cos_nuv)

        self.concatenate_results()
        f26 = read_f26('.all_results')
        self.options['MODEL']['absorbers'] = f26.absorbers

        if f26.absorbers is not None:
            self.update_plot(self.redshift)

        self.last_loaded = None

    def on_cos_fuv_checkbox(self, state):

        if state == Qt.Checked:
            self.cos_fuv = True

        else:
            self.cos_fuv = False

    def on_cos_nuv_checkbox(self, state):

        if state == Qt.Checked:
            self.cos_nuv = True

        else:
            self.cos_nuv = False

    def on_include_checkbox(self, state):

        if state == Qt.Checked:
            self.include = True

        else:
            self.include = False

    def on_resolution(self):

        resolution, ok = SpectralResolutionDialog.get_spectral_resolution(
            self.main_frame)

        if ok:
            self.resolution = resolution

    def on_help(self):

        QMessageBox.information(self.main_frame, 'Help', info, False)

    def on_buttonpress(self, event):

        if event.inaxes is None:
            return

        i = self.axes.index(event.inaxes)
        transition = self.transitions[np.where(self._ind == i)[0]]

        z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
        wavelength = transition.wavelength.value * (1 + z)

        isort = np.argsort(self.ticks['wavelength'])
        wavelengths = self.ticks['wavelength'][isort]
        transitions = self.ticks['transition'][isort]

        idx = wavelengths.searchsorted(wavelength)
        wavelength = wavelengths[idx]
        transition = atom.get_transition(transitions[idx])
        z = wavelength / transition.wavelength.value - 1

        message = '{0}, z = {1:.3f}'.format(transition.name, z)
        QMessageBox.information(self.main_frame, 'Transition', message, False)

    def on_keypress(self, event):

        if event.key == ' ' and event.inaxes is not None:

            z = self.redshift

            # Get amount to add to redshift:
            dz = (event.xdata / c_kms) * (1 + z)

            # Get new axis limits, if any:
            vmin, vmax = event.inaxes.get_xlim()
            self.vmin = min(0, vmin)
            self.vmax = max(0, vmax)
            self.update_plot(z + dz)

        if event.key == 'z':

            redshift, ok = QInputDialog.getText(
                self.main_frame, 'New Redshift', 'Enter redshift: ', False)

            if ok:
                self.update_plot(float(redshift))

        if event.key == 'b':

            i = self.axes.index(event.inaxes)
            transition = self.transitions[np.where(self._ind == i)[0]]

            z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
            wavelength = transition.wavelength.value * (1 + z)

            if (self.previous_keypress == 'b' and
                    self.previous_wavelength is not None):

                wmin = self.previous_wavelength
                wmax = wavelength

                if wmin > wmax:
                    wmin, wmax = wmax, wmin

                print('%% {0} 1 {1:.3f} {2:.3f} vfwhm=10.0'.format(
                    self.filename, wmin, wmax))

                self.previous_keypress = None
                self.previous_wavelength = None

            else:
                self.previous_wavelength = wavelength

        if event.key == 'l':

            from ..calculations.absorption import logn_from_tau_peak

            i = self.axes.index(event.inaxes)
            transition = self.transitions[np.where(self._ind == i)[0]]

            z = (1 + event.xdata / c_kms) * (1 + self.redshift) - 1
            wavelength = transition.wavelength.value * (1 + z)
            index = self.wavelength.searchsorted(wavelength)

            flux = self.flux[index - 1:index + 1]
            error = self.error[index - 1:index + 1]
            continuum = self.continuum[index - 1:index + 1]
            flux_norm = flux / continuum
            error_norm = error / continuum

            valid = (error_norm > 0) & ~np.isnan(flux_norm)

            if not any(valid):
                print('No good pixels!')
                return

            flux_norm = np.median(flux_norm[valid])
            error_norm = np.median(error_norm[valid])

            if flux_norm < error_norm:
                flux_norm = error_norm

            elif flux_norm > 1 - error_norm:
                flux_norm = 1 - error_norm

            b = 20  # assume 20 km/s
            tau = -np.log(flux_norm)
            logn = logn_from_tau_peak(transition, tau, b)

            print('{0:6s} {1:8.6f} 0.0 {2:4.1f} 0.0 {3:4.1f} 0.0'.format(
                transition.parent, z, b, logn))

        if event.key == 'S':

            filename, ok = QInputDialog.getText(
                self.main_frame, 'Save Figure', 'Enter filename: ', False)

            if ok:
                self.savefig(filename)

        self.previous_keypress = event.key

    def connect(self):
        cids = dict()
        cids['key_press_event'] = self.canvas.mpl_connect(
            'key_press_event', self.on_keypress)
        cids['button_press_event'] = self.canvas.mpl_connect(
            'button_press_event', self.on_buttonpress)
        self.cids.update(cids)
Exemplo n.º 13
0
class mpl_widget(QWidget):
    def __init__(self, parent=None, mainWidget=None):
        self._SELECTEDCELLS = list()       # container for instances of selected cells, so we can delete them when we want
        self._SELECTEDCELLS_IJ = list()  # container for coords of selected cells, so we can delete them when we want
        self._SELECTEDCELLLINES = list()   # container for instances of selected cells, so we can delete them when we want
        self._GRIDLINES = None
        QWidget.__init__(self, parent)
        self.mainWidget = mainWidget
        self.create_main_frame()
        self.mpl_menu = mpl_menu(self)
        self.shift_is_held = False
        #self.connect(self.mpl_menu, QtCore.SIGNAL('mySignal'), self.mySlot)
        #print 'my parent is:', parent
        self.clear_selection()
        self.init_tooltips()

    def init_tooltips(self):
        self.canvas.setToolTip('If 2D plot => RMB click toggles menu <br> - RMB click selects cell <br> - selected cells are drawn with black border')
        self.grid_cb.setToolTip('If 2D plot => show computational grid <br> If 1D plot => show normal gridlines')
        self.cbar_button.setToolTip('If 2D plot => controls the color range. <br> Note: <br> - pressing UP and DOWN arrows cycles through colormaps <br> - dragging colorbar with RMB scales the color-range <br> - dragging colorbar with LMB shifts the color-range')
        self.mpl_toolbar.setToolTip('Shows coordinates (i,j, lat,lon) and data-value(z) under the cursor. <br> if you see <i>>>></i> coordinates are not visible. Enlarge the window')

    def create_main_frame(self):

        self.fig = Figure(dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy( Qt.ClickFocus )
        self.canvas.setFocus()

        self.mpl_toolbar = myNavigationToolbar(self.canvas, self)
        self.canvas.mpl_connect('button_press_event', self.on_click)
        self.canvas.mpl_connect('key_press_event', self.on_key_press)
        self.canvas.mpl_connect('key_release_event', self.on_key_release)
        #self.canvas.mpl_connect('button_press_event', self.disable_clicks)


        self.cbar_button = QPushButton("Color Range")
        self.cbar_button.setFocusPolicy( Qt.NoFocus )
        self.grid_cb = QCheckBox("Show Grid")
        self.grid_cb.setFocusPolicy( Qt.NoFocus )
        self.grid_cb.stateChanged.connect(self.showGrid)

        vbox = QVBoxLayout()
        hbox = QHBoxLayout()

        vbox.addWidget(self.canvas)  # the matplotlib canvas
        hbox.addWidget(self.mpl_toolbar)
        hbox.addWidget(self.cbar_button)
        hbox.addWidget(self.grid_cb)
        vbox.addLayout(hbox)
        self.setLayout(vbox)



    def on_click(self, event):
        if event.inaxes != self.get_axes()[0]: return
        #if self.get_axes()[0].format_coord(event.x, event.y) == 'outside data area': return
        if self.allow_menu():
            self.allow_popup_menu = True
            if self.shift_is_held:
                self.allow_popup_menu = False

            point = [int(event.xdata + .5), int(event.ydata + .5)]
            #print '>>>', point, '\t currently {0} selected'.format(len(self._SELECTEDCELLS))
            if event.button == 3 :  #if RMB is clicked

                # working with dialog for transect!
                if self.mainWidget.transect_dlg:
                    if self.mainWidget.transect_dlg.toogle_show_after_selected_cell:
                        realx, realy = self.get_real_xy(event.xdata, event.ydata, self.mainWidget.detect_variable_dimensions())
                        realpoint = [realy, realx]
                        #print 'real xy:', realpoint
                        if self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p1(realpoint)
                        elif self.mainWidget.transect_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.transect_dlg.data.set_p2(realpoint)

                        self.mainWidget.transect_dlg.update()
                        self.mainWidget.transect_dlg.show()
                
                # working with dialog for flux!
                if self.mainWidget.flux_dlg:
                    if self.mainWidget.flux_dlg.toogle_show_after_selected_cell:
                        if self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 1:  # select point 1
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p1(point)
                        elif self.mainWidget.flux_dlg.toogle_show_after_selected_cell == 2:  # select point 2
                            self.allow_popup_menu = False
                            self.mainWidget.flux_dlg.data.set_p2(point)

                        self.mainWidget.flux_dlg.update()
                        self.mainWidget.flux_dlg.show()



                if len(self._SELECTEDCELLS) == 0:  # if no cell is selected
                    self.add_selected_cell(point)


                else:  # if some cells are already selected
                    if self.mpl_menu.allow_rmb_select_cells() or self.shift_is_held:
                        # check if this point is already selected:
                        already_selected = False
                        for p in self._SELECTEDCELLS_IJ:
                            if (point[0] == p[0]) and (point[1] == p[1]):
                                already_selected = True
                                print 'cell already selected... is not added'

                        if not already_selected:
                            self.add_selected_cell(point)
                    else:
                        pass
                        #self.clear_selection()
                        #self.add_selected_cell(point)

    def cells_selected(self):
        if self._SELECTEDCELLS: return len(self._SELECTEDCELLS)
        else: return False

    def add_selected_cell(self, point):
        ''' point = [i, j]'''
        print 'selected cell:', point[0], point[1]
        c = self.draw_picked_cell(point)
        self._SELECTEDCELLS.append(c)
        self._SELECTEDCELLS_IJ.append(point)




    def get_selected_cells_ij(self):
        return self._SELECTEDCELLS_IJ

    def clear_selection(self):
        '''
        delete all graphical objects of selected cells
        redraw canvas
        '''
        print 'clearing stuff'
        if len(self._SELECTEDCELLLINES) > 0:
            for line in self._SELECTEDCELLLINES:
                l = line.pop(0)
                l.remove()
                del l
            del self._SELECTEDCELLLINES[:]
        #print 'cells ---- before:', len(self._SELECTEDCELLS)
        if len(self._SELECTEDCELLS) > 0:
            for cell in self._SELECTEDCELLS:
                for line in cell:
                    l = line.pop(0)
                    l.remove()
                    del l
            del self._SELECTEDCELLS[:]
        #print 'cells ---- left:', len(self._SELECTEDCELLS)


        #print 'cells-coords ----'
        #print len(self._SELECTEDCELLS_IJ)
        if self._SELECTEDCELLS_IJ:
            for cellcoords in self._SELECTEDCELLS_IJ:
                #cc = cellcoords.pop(0)
                #cellcoords.remove()
                del cellcoords
            del self._SELECTEDCELLS_IJ[:]
        #print 'cells ---- left,', len(self._SELECTEDCELLS_IJ)



        if len(self._SELECTEDCELLS) != 0:
            raise ValueError('List "self._SELECTEDCELLS" was not flushed')

        if len(self._SELECTEDCELLLINES) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')

        if len(self._SELECTEDCELLS_IJ) != 0:
            raise ValueError('List "self._SELECTEDCELLLINES" was not flushed')
        # update plot
        self.canvas.draw()
        #print 'finishing clear: cells left', len(self._SELECTEDCELLS)


    def showGrid(self, state):
        if self.fig.axes:
            current_plot = self.mainWidget.get_plotType()
            current_plot2D = self.mainWidget.get_plotType_for_timeseries()
            if state == Qt.Checked:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(True)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(True)
            else:
                if current_plot == '1D' or (current_plot2D =="2DZT"):
                    self.fig.axes[0].grid(False)
                elif current_plot == '2D' and (not current_plot2D =="2DZT"):
                    self.draw_pixel_grid(False)
            self.canvas.draw()

    def draw_picked_cell(self, point):
        x = point[0]
        y = point[1]
        '''
        approach drawing a patch... not working
        cell_bnd = patches.Rectangle((x-.5, y-.5), 1, 1, fill=False, edgecolor="black", hatch=None, linewidth=1.)
        cell_instance = self.fig.axes[0].add_patch(cell_bnd)
        '''

        b_line = [(x-.5, x+.5), (y-.5, y-.5)]
        r_line = [(x+.5, x+.5), (y-.5, y+.5)]
        t_line = [(x-.5, x+.5), (y+.5, y+.5)]
        l_line = [(x-.5, x-.5), (y-.5, y+.5)]
        cell = [b_line, r_line, t_line, l_line]
        for i, l in enumerate(cell):
            ll = self.fig.axes[0].plot(l[0], l[1], 'k-', lw=.8)
            cell[i] = ll  # overwriting current Line2D object with object binded to an axes
        #self._SELECTEDCELLS.append(cell)  # collecting reference to this cell to be able to delete it
        #self._SELECTEDCELLS_IJ.append(point)  # collecting reference to this cell to be able to delete it

        self.canvas.draw()
        return cell


    def draw_line(self, point1, point2):
        line = [(point1[0], point2[0]), (point1[1], point2[1])]
        l = self.fig.axes[0].plot(line[0], line[1], 'k-', lw=2)
        return l

    def draw_pixel_grid(self, enable=True):
        if enable:
            dx = 1
            dy = 1
            x0 = -.5
            y0 = -.5

            if self.mainWidget.get_plotType_for_timeseries() == '2DXY':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nY()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZY':
                nx = self.mainWidget.get_nY()
                ny = self.mainWidget.get_nZ()
            elif self.mainWidget.get_plotType_for_timeseries() == '2DZX':
                nx = self.mainWidget.get_nX()
                ny = self.mainWidget.get_nZ()

            self._GRIDLINES = list()
            for n_hline in np.arange(ny+1):
                hline = [(x0, x0+nx), (y0+n_hline, y0+n_hline)]
                l = self.fig.axes[0].plot(hline[0], hline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it

            for n_vline in np.arange(nx+1):
                vline = [(x0+n_vline, x0+n_vline), (y0, y0+ny)]
                l = self.fig.axes[0].plot(vline[0], vline[1], 'k-', lw=.2)
                self._GRIDLINES.append(l)  # collecting reference to this line to be able to delete it


        if not enable:
            #print 'deleting lines...'
            if self._GRIDLINES:  # if lines were created
                #print 'lines are here...'
                for line in self._GRIDLINES:
                    #print line
                    l = line.pop(0)
                    l.remove()
                    del l
            self.fig.canvas.draw()

    def on_key_press(self, event):
        #print 'key pressed:', event.key
        if event.key == 'shift':
            self.shift_is_held = True


    

    def on_key_release(self, event):
        #print 'key released:', event.key
        if event.key == 'shift':
            self.shift_is_held = False

        elif event.key == 'escape':
            self.clear_selection()


    def change_coordinate_formatter(self, ax, data2d,  bruteforce_flag=None, bruteforce_dims=None):
        ''' see http://stackoverflow.com/questions/14754931/matplotlib-values-under-cursor
        '''
        numrows, numcols = data2d.shape
        bruteforce_mode_on = False
        bruteforce_mode_on = (bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2])


        def format_coord(x, y):
            col = int(x+0.5)
            row = int(y+0.5)

            if not bruteforce_mode_on:
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    return 'i=%d j=%d z=%.6f' % (col, row, z)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'

            elif bruteforce_flag == '2DXY' and bruteforce_dims[-1] and bruteforce_dims[-2]:
                '''
                our extend in X=[-0.5:numcols-0.5], Y=[-0.5:numrows-0.5], because col,row is cell center!
                '''
                if col >= 0 and col < numcols and row >= 0 and row < numrows:
                    #z = data2d[row, col]
                    # sice we have artificially reversed y-coordinate axes, now reverse data!
                    # numrows-1, because if nrows=10 => row=[0:9]
                    z = data2d[numrows-1-row, col]
                    real_x, real_y = self.get_real_xy(x, y, bruteforce_dims)

                    #return 'x=%1.1f y=%1.1f z=%1.6f' % (x, y, z)
                    #return 'i=%d j=%d z=%.3f x=%.4f y=%.4f' % (col, row, z, real_x, real_y)
                    return 'i=%d j=%d z=%.3f, %s=%.2f %s=%.2f' % (
                        col, row, z, bruteforce_dims[-1], real_x, bruteforce_dims[-2], real_y)
                else:
                    #return 'x=%1.4f, y=%1.4f' % (x, y)
                    return 'outside data area'
            else:
                raise ValueError('bruteforce_flag can be $None$ or $"2DXY"$. Passed %s' % bruteforce_flag)
        ax.format_coord = format_coord


    def allow_menu(self):
        allow = False
        #print "self.mainWidget.get_plotType():", self.mainWidget.get_plotType()
        #print "self.mainWidget.get_plotType_for_timeseries():", self.mainWidget.get_plotType_for_timeseries()
        if self.mainWidget.get_plotType() == "2D" and not self.mainWidget.get_plotType_for_timeseries() == "2DZT":
            allow = True
        return allow
    

    def get_real_xy(self, i, j, dimension_list):
        '''
        functions returns values of x,y based on passed indexes i, j

        '''
        if any(dimension_list[-2:-1]) is None:
            print 'Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)'
            raise ValueError('Dimensions X,Y of current variable are not specified (variables that have same name as dimensions not found)')
        nc = self.mainWidget.get_selected_ncfile_instance()
        try:
            x_var = nc.variables[dimension_list[-1]]
            y_var = nc.variables[dimension_list[-2]]
            
        except:
            
            print ('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))
            raise ValueError('Failed to load variables: {0}, {1}'.format(dimension_list[-1], dimension_list[-2]))


        x_ratio = (x_var[-1]-x_var[0])/(len(x_var)-1)
        y_ratio = (y_var[-1]-y_var[0])/(len(y_var)-1)

        #x[i] = x_var[0]+x_ratio*i
        #y[j] = y_var[0]+y_ratio*j
        x = x_var[0] + x_ratio*i
        y = y_var[0] + y_ratio*j
        nc.close()
        return (x, y)

    def get_axes(self):
        return self.fig.get_axes()
    

    def fast_redraw(self, artist):
        background = [self.canvas.copy_from_bbox(self.get_axes()[0].bbox)]
        self.get_axes()[0].draw_artist(artist)
        self.canvas.restore_region(background)
        self.canvas.blit(self.get_axes()[0].bbox)
        self.canvas.update()
        self.canvas.flush_events()