Esempio n. 1
0
class InitHist(object):
    #this is the fryplot init - will this work for the histogram?
    def __init__(self, plotTarget, barTarget, col=0, row=0):
        # add matplotlib figure to dialog
        self.plotTarget = plotTarget
        self.barTarget = barTarget
        self.col = col
        self.row = row
        self.setupFigure()

    def setupFigure(self):
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        self.mpltoolbar = NavigationToolbar(self.canvas, self.barTarget)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.plotTarget.addWidget(self.canvas, self.row, self.col)
        self.plotTarget.addWidget(self.mpltoolbar)

        # and configure matplotlib params
        rcParams["font.serif"] = "Verdana, Arial, Liberation Serif"
        rcParams["font.sans-serif"] = "Tahoma, Arial, Liberation Sans"
        rcParams["font.cursive"] = "Courier New, Arial, Liberation Sans"
        rcParams["font.fantasy"] = "Comic Sans MS, Arial, Liberation Sans"
        rcParams["font.monospace"] = "Courier New, Liberation Mono"

    def histPlotter(self, lenList, title):

        self.axes.clear()
        self.axes.set_title(title)
        x = lenList

        count, bin, self.bar = self.axes.hist(x)
        self.figure.canvas.draw()

    def resetFigure(self):
        #plt.close(self.figure)
        #self.setupFigure()
        try:
            t = [b.remove() for b in self.bar]
        except:
            pass
        self.figure.canvas.draw()
Esempio n. 2
0
class Averager(QMainWindow, Ui_Averager):
    def __init__(self):
        super(Averager, self).__init__()
        self.setupUi(self)
        # state variable
        self.idle = True
        # number of samples to show on the plot
        self.size = 8193 # max size
        # buffer and offset for the incoming samples
        self.buffer = bytearray(4 * self.size)
        self.offset = 0
        self.data = np.frombuffer(self.buffer, np.int32)
        # create figure
        figure = Figure()
        figure.set_facecolor('none')
        self.axes = figure.add_subplot(111)
        self.canvas = FigureCanvas(figure)
        self.plotLayout.addWidget(self.canvas)
        # create navigation toolbar
        self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
        # remove subplots action
        actions = self.toolbar.actions()
        self.toolbar.removeAction(actions[7])
        self.plotLayout.addWidget(self.toolbar)
        # create TCP socket
        self.socket = QTcpSocket(self)
        self.socket.connected.connect(self.connected)
        self.socket.readyRead.connect(self.read_data)
        self.socket.error.connect(self.display_error)        
        self.cbShowComp.clear()
        self.cbShowComp.addItems(["Real", "Imaginary", "Absolute", "Phase"])
        self.cbShowComp.setCurrentIndex(2);
        
        #connections
        self.btnStart.clicked.connect(self.start)
        self.txtNOA.valueChanged.connect(self.update_values)
        self.txtNOS.valueChanged.connect(self.update_values)
        self.chkFFT.stateChanged.connect(self.update_values)
        self.chkScale.stateChanged.connect(self.update_values)
        self.chkLogScale.stateChanged.connect(self.update_values)
        self.cbShowComp.currentIndexChanged.connect(self.update_values)
        self.isScaled = True
        self.isLogScale = False
        self.isFFT = False
        self.haveData = False
        self.showComp = 0 # Real, Imag, Abs, Phase from combo box
        
        
    def update_values(self):
        self.labNOA.setText(str((1<<int(self.txtNOA.text()))))
        self.labNOS.setText(str((1<<int(self.txtNOS.text()))))
        self.isScaled = self.chkScale.isChecked()
        self.isLogScale = self.chkLogScale.isChecked()
        self.isFFT = self.chkFFT.isChecked()
        self.showComp = self.cbShowComp.currentIndex()
        self.plot()
        
    
    def start(self):
        if self.idle:
            print "connecting ..."
            self.btnStart.setEnabled(False)
            self.socket.connectToHost(self.txtIPA.text(), 1001)
        else:
          self.idle = True
          self.socket.close()
          self.offset = 0
          self.btnStart.setText('Start')
          self.btnStart.setEnabled(True)
          print "Disconnected"
    
    def setConfig(self):
        # Number of Samples
        self.size = (1<<int(self.txtNOS.text()))
        self.naverages = (1<<int(self.txtNOA.text()))
        #print "number of samples = " + str(self.size)

        if self.idle: return
        self.socket.write(struct.pack('<I', 1<<28 | int(self.txtTD.text())))
        self.socket.write(struct.pack('<I', 2<<28 | int(self.txtNOS.text())))
        self.socket.write(struct.pack('<I', 3<<28 | int(self.txtNOA.text())))
        #print "Configuration sent"
    
    def connected(self):
        print "Connected"
        self.idle = False
        self.btnStart.setText('Stop')
        self.btnStart.setEnabled(True)
        self.setConfig()    
        self.fire()
        

    def read_data(self):
        size = self.socket.bytesAvailable()
        print "got  " + str(size) 
        if self.offset + size < 4*self.size:
          self.buffer[self.offset:self.offset + size] = self.socket.read(size)
          self.offset += size
        else:
          #print "have all data"
          self.buffer[self.offset:4*self.size] = self.socket.read(4*self.size - self.offset)
          self.offset = 0
          self.haveData = True
          self.plot()

          self.idle = True
          self.socket.close()
          self.offset = 0
          self.btnStart.setText('Start')
          self.btnStart.setEnabled(True)
          print "Disconnected"
          
          
    def plot(self):
        
        if self.haveData == False: return
            
        # reset toolbar
        self.toolbar.home()
        self.toolbar._views.clear()
        self.toolbar._positions.clear()
        # reset plot
        self.axes.clear()
        self.axes.grid()
        # set data
        self.time_step = 1./125 # us
        y_data = np.array(self.data[0:self.size], dtype=float)
        N = self.size; # number of complex samples
        
        # scale
        y_data = y_data/self.naverages
            
        x_data = np.arange(1,N+1)
        xlab = "Index"
        ylab = "14-bit ADC output"
        

        if self.isScaled == True:
            self.gnd = 0*-146.6
            self.vcc = 1133.7;
            y_data = 4.96*(y_data - self.gnd)/(self.vcc-self.gnd)         
            x_data = self.time_step*x_data
            xlab = 'Time (us)'
            ylab = 'Voltage'

        
        if self.isFFT == True:

            y_data[-1] = (y_data[0]+y_data[-2])/2
            y_data = np.fft.fft(y_data)/N
            x_data = np.fft.fftfreq(y_data.size, self.time_step)
            x_data = np.fft.fftshift(x_data)
            y_data = np.fft.fftshift(y_data)
            xlab = 'Frequency (MHz)'
            ylab = 'Amplitude'
            
        if self.showComp == 0:
            y_data = y_data.real
            ylab = "Real " + ylab
        elif self.showComp == 1:
            y_data = y_data.imag
            ylab = "Imag " + ylab
        elif self.showComp == 2:
            y_data = np.abs(y_data)
            ylab = "Abs " + ylab
        else:
            y_data = np.angle(y_data)
            ylab = "Phase " + ylab
            
        if self.isLogScale == True:
            y_data = 20*np.log10(y_data)
            ylab = ylab + ' (dBV)'
        else:
            ylab = ylab + ' (V)'
            
        #print str(y_data[N/2-1]) + " " + str(y_data[N/2]) + " " + str(y_data[N/2+1])
        self.curve = self.axes.plot(x_data, y_data)
        #x1, x2, y1, y2 = self.axes.axis()
        # set y axis limits
        #self.axes.axis((1, self.size, -1500,500))
        self.axes.set_xlim([min(x_data), max(x_data)])
        self.axes.set_xlabel(xlab)
        self.axes.set_ylabel(ylab)
        self.canvas.draw()

    def display_error(self, socketError):
        if socketError == QAbstractSocket.RemoteHostClosedError:
            pass
        else:
            QMessageBox.information(self, 'Averager', 'Error: %s.' % self.socket.errorString())
        self.btnStart.setText('Start')
        self.btnStart.setEnabled(True)
    
    
    def fire(self):
        if self.idle: return
        self.socket.write(struct.pack('<I', 0<<28))
Esempio n. 3
0
class ProfileFromPointsDialog(QtWidgets.QDialog, FORM_CLASS):
    proj = QgsProject.instance()

    def __init__(self, parent=None):
        """Constructor."""
        super(ProfileFromPointsDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        # add matplotlib figure to dialog
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        #        self.figure.subplots_adjust(left=.1, bottom=0.15, right=.78, top=.9, wspace=None)
        self.mplCanvas = FigureCanvas(self.figure)

        self.mpltoolbar = NavigationToolbar(self.mplCanvas, self.toolbarWidget)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.layoutPlot.addWidget(self.mplCanvas)
        self.layoutPlot.addWidget(self.mpltoolbar)
        self.figure.patch.set_visible(False)
        self.layoutPlot.minimumSize()

        ##connections
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.uPointLayer.currentIndexChanged.connect(self.reloadFields)

        self.uLineLayer.currentIndexChanged.connect(self.checkSelectedLine)
        self.uCopytoClip.clicked.connect(self.copyClipboard)

        self.manageGui()

    def manageGui(self):
        # print('manageGui')
        self.uPointLayer.clear()
        Lstptos = utils.getPointLayerNames()
        self.uPointLayer.addItems(Lstptos)
        #try to find activelayer and select it in the point combobox
        try:
            lyrName = qgis.utils.iface.activeLayer().name()
            if lyrName in Lstptos:
                self.uPointLayer.setCurrentText(lyrName)
        except Exception as e:
            print('Erro:', str(e))
            pass
        self.uLineLayer.clear()
        self.uLineLayer.addItems(utils.getLineLayerNames())

    def reloadFields(self):
        # print('reload fields')
        self.uZfield.clear()
        self.uPointID.clear()
        self.uOrderField.clear()

        self.axes.clear()

        point_layer = self.proj.mapLayersByName(
            self.uPointLayer.currentText())[0]  #processing.getObject(str())
        if point_layer.selectedFeatureCount() != 0:
            self.uSelectedPoints.setCheckState(Qt.Checked)
        else:
            self.uSelectedPoints.setCheckState(Qt.Unchecked)

        self.uZfield.addItems(
            utils.getFieldNames(point_layer, [QVariant.Int, QVariant.Double]))
        self.uOrderField.addItems(
            utils.getFieldNames(point_layer, [QVariant.Int, QVariant.Double]))
        self.uPointID.addItems(
            utils.getFieldNames(
                point_layer,
                [QVariant.Int, QVariant.Double, 10]))  # 10 is for string

    def checkSelectedLine(self):
        ###print 'check if line layer selected'
        line_layer = self.proj.mapLayersByName(
            self.uLineLayer.currentText())[0]  #processing.getObject(str())
        if line_layer:
            if line_layer.selectedFeatureCount() != 0:
                self.uSelectedLine.setCheckState(Qt.Checked)
            else:
                self.uSelectedLine.setCheckState(Qt.Unchecked)

    def copyClipboard(self):
        if self.values is None:
            return
        else:
            clipboard = QApplication.clipboard()
            if self.uNoHeader.isChecked():
                clipboard.setText('\n'.join(
                    '%s\t%s' % x for x in zip(self.values[0], self.values[1])))
            else:
                clipboard.setText('distance\televation\tpointID\n' + '\n'.join(
                    '%s\t%s\t%s' % x for x in zip(
                        self.values[0], self.values[1], self.values[2])))

    def restoreGui(self):
        self.buttonBox.rejected.connect(self.reject)
        self.btnClose.clicked.disconnect(self.stopProcessing)
        self.btnClose.setText(self.tr("Close"))
        self.btnOk.setEnabled(True)
        self.uprogressBar.setMaximum(100)

    def refreshPlot(self):
        self.axes.clear()

        if self.values is None:
            return

        self.axes.plot(np.array(self.values[0]), np.array(self.values[1]))

        ###to draw labels from jorgealmerio
        if self.uPointIDlabels.isChecked():
            for i, linha in enumerate(np.array(self.values[2])):
                id = self.values[2][i]
                dist = self.values[0][i]
                z = self.values[1][i]
                self.axes.annotate(id, (dist, z))

        self.axes.grid()
        formatter = ScalarFormatter(useOffset=False)
        self.axes.yaxis.set_major_formatter(formatter)

        self.axes.set_ylabel(str(self.tr("Elevation, z field units")))
        self.axes.set_xlabel(str(self.tr('Station, layer units')))

        self.mplCanvas.draw()

    def buildLine(self, pointSelectFlag):
        # print('buildLine')
        pointLayer = self.proj.mapLayersByName(
            self.uPointLayer.currentText())[0]  #processing.getObject(str())
        orderField = self.uOrderField.currentText()
        sortOrder = self.uOrder.currentText()
        crs = pointLayer.crs().toWkt()

        pointList = []
        if pointSelectFlag:
            pointFeatureList = pointLayer.selectedFeatures()
        else:
            pointFeatureList = pointLayer.getFeatures()
        for pointFeature in pointFeatureList:
            pointGeom = pointFeature.geometry()
            coords = pointGeom.asPoint()
            sortField = pointFeature[orderField]
            ##store data
            pointList.append([coords, sortField])

        if not pointFeatureList:
            QMessageBox.warning(self, 'Error', 'Selected point list is empty')
            return 'Error'
        ###sort data by field
        if sortOrder == 'Ascending':
            pointList = sorted(pointList, key=itemgetter(1))
        else:
            pointList = sorted(pointList, key=itemgetter(1), reverse=True)

        ## drop sort field
        pointList = list(zip(*pointList))[0]  #list(zip(*pointList)[0])

        ###build line
        # create a new memory layer
        newLineLayer = QgsVectorLayer("LineString?crs=" + crs,
                                      "profileFromPointsLine", "memory")
        pr = newLineLayer.dataProvider()
        feat = QgsFeature()
        geom = QgsGeometry.fromPolylineXY(pointList)
        feat.setGeometry(geom)
        pr.addFeatures([feat])

        newLineLayer.updateExtents()
        QgsProject.instance().addMapLayers([newLineLayer])
        return newLineLayer

    def accept(self):
        # print('run')
        pointLayer = self.proj.mapLayersByName(
            self.uPointLayer.currentText())[0]  #processing.getObject(str())
        # check for selected features
        if self.uSelectedPoints.isChecked():
            pointSelectFlag = True
        else:
            pointSelectFlag = False
        if self.uSelectedLine.isChecked():
            lineSelectFlag = True
        else:
            lineSelectFlag = False
        ## check if need to build line
        if self.utabWidget.currentIndex() == 0:
            lineLayer = self.buildLine(pointSelectFlag)
            if lineLayer == 'Error':
                return
        else:
            lineLayer = self.proj.mapLayersByName(
                self.uLineLayer.currentText())[0]  #processing.getObject(str())

        zField = self.uZfield.currentText()
        pointIdField = self.uPointID.currentText()
        try:
            noData = float(self.lineEditNoData.text())
        except:
            QMessageBox.warning(self, 'Error', 'No data value must be numeric')
            return
        if self.uBuffer.displayText() != '':
            buff = float(self.uBuffer.displayText())
        else:
            buff = None

        # trap for coordinate system
        if lineLayer.crs() != pointLayer.crs():
            QMessageBox.warning(
                self, 'Error',
                'Point layer coordinate system does not match line coordinate system'
            )
            return

        # trap for more than one line feature
        counter = 0
        if lineSelectFlag:
            lineFeatureList = lineLayer.selectedFeatures()
        else:
            lineFeatureList = lineLayer.getFeatures()

        for lineFeatures in lineFeatureList:
            counter = counter + 1

        if counter != 1:
            QMessageBox.warning(self, 'Error',
                                'More than one line feature in line layer')
            return

        if lineSelectFlag:
            lineFeat = lineLayer.selectedFeatures()[0]
        else:
            lineFeat = next(lineLayer.getFeatures())
        lineGeom = lineFeat.geometry()
        if lineGeom.isMultipart:
            polilinha = lineGeom.asMultiPolyline()[0]  #get only first
        else:
            polilinha = lineGeom.asPolyline()
        lineShap = LineString(polilinha)
        if buff:
            lineBoundary = lineShap.buffer(buff)

        if pointSelectFlag:
            pointFeatureList = pointLayer.selectedFeatures()
        else:
            pointFeatureList = pointLayer.getFeatures()
        pointList = []
        for pointFeature in pointFeatureList:
            pointGeom = pointFeature.geometry()
            pointShap = Point(pointGeom.asPoint())
            if buff:
                ## check if point is within line buffer
                if pointShap.within(lineBoundary):
                    z = pointFeature[zField]
                    ### get distance along line
                    dist = lineShap.project(pointShap)
                    pointId = pointFeature[pointIdField]
                    ##store data
                    pointList.append([dist, z, pointId])
            else:
                z = pointFeature[zField]
                ### get distance along line
                dist = lineShap.project(pointShap)
                pointId = pointFeature[pointIdField]
                ##store data
                pointList.append([dist, z, pointId])
        ###sort data by distance
        pointList = sorted(pointList, key=itemgetter(0))
        ###seperate data back into individual lists
        zList = []
        distList = []
        pointIdList = []
        for i in pointList:
            ## only keep data that is not flaged as noData
            if i[1] != noData:
                distList.append(i[0])
                zList.append(i[1])
                pointIdList.append(i[2])
        self.values = [distList, zList, pointIdList]
        self.refreshPlot()
        self.uCopytoClip.setEnabled(True)
class kmeansDialog(QtGui.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(kmeansDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

        # add matplotlib figure to dialog
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        self.mpltoolbar = NavigationToolbar(self.canvas, self.widgetPlot)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.layoutPlot.addWidget(self.canvas)
        self.layoutPlot.addWidget(self.mpltoolbar)

        # and configure matplotlib params
        rcParams["font.serif"] = "Verdana, Arial, Liberation Serif"
        rcParams["font.sans-serif"] = "Tahoma, Arial, Liberation Sans"
        rcParams["font.cursive"] = "Courier New, Arial, Liberation Sans"
        rcParams["font.fantasy"] = "Comic Sans MS, Arial, Liberation Sans"
        rcParams["font.monospace"] = "Courier New, Liberation Mono"

        self.values = None
        self.outPath = None

        self.btnOk = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)
        self.openBtn.clicked.connect(self.saveFile)

        self.chkShowGrid.stateChanged.connect(self.refreshPlot)
        self.chkAsPlot.stateChanged.connect(self.refreshPlot)
        self.btnRefresh.clicked.connect(self.refreshPlot)

        self.manageGui()
        self.axes.set_title(unicode(self.tr(u"Statistic Plot")))

    def manageGui(self):
        self.cmbLayers.clear()
        self.cmbLayers.addItems(utils.getVectorLayerNames())

        self.btnRefresh.setEnabled(False)
		
    def accept(self):
        self.axes.clear()
        self.spnMinX.setValue(0.0)
        self.spnMaxX.setValue(0.0)
        self.lstStatistics.clearContents()
        self.lstStatistics.setRowCount(0)

        layer = utils.getVectorLayerByName(self.cmbLayers.currentText())

        statData = self.kmeansCluster(layer, self.cmbDis.currentIndex(), self.spnNum.value())
        self.processFinished(statData)
        self.addClassField(layer)
        self.progressBar.setValue(0)

    def reject(self):
        QDialog.reject(self)

    def setProgressRange(self, maxValue):
        self.progressBar.setRange(0, maxValue)

    def updateProgress(self):
        self.progressBar.setValue(self.progressBar.value() + 1)

    def processFinished(self, statData):
        # populate table with results
        self.tableData = statData[0]
        self.values = statData[1]
        rowCount = len(self.tableData)
        self.lstStatistics.setRowCount(rowCount)
        for i in xrange(rowCount):
            item = QTableWidgetItem(self.tr("%d") % (i))
            self.lstStatistics.setItem(i, 0, item)
            tmp = self.tableData[i]
            item = QTableWidgetItem(self.tr("%f") % (tmp[0]))
            self.lstStatistics.setItem(i, 1, item)
            item = QTableWidgetItem(self.tr("%f") % (tmp[1]))
            self.lstStatistics.setItem(i, 2, item)

        self.lstStatistics.resizeRowsToContents()

        self.btnRefresh.setEnabled(True)

        # create histogram
        self.refreshPlot()

    def saveFile(self):
        self.outPath = QFileDialog.getSaveFileName(self, u'保存文件',u"map","jpg(*.jpg)")
        self.lineEdit.setText(self.outPath)

    def refreshPlot(self):
        self.axes.clear()
        self.axes.set_title(unicode(self.tr("Statistic Plot")))
        interval = None

        if self.values is None:
            return

        if self.spnMinX.value() == self.spnMaxX.value():
            pass
        else:
            interval = []
            if self.spnMinX.value() > self.spnMaxX.value():
                interval.append(self.spnMaxX.value())
                interval.append(self.spnMinX.value())
            else:
                interval.append(self.spnMinX.value())
                interval.append(self.spnMaxX.value())

        if not self.chkAsPlot.isChecked():
            self.axes.hist(self.values, 18, interval, alpha=0.5, histtype="bar")
            #self.axes.plot(self.values, "ro-")
        else:
            n, bins, pathes = self.axes.hist(self.values, 18, interval, alpha=0.5, histtype="bar")
            self.axes.clear()
            c = []
            for i in range(len(bins) - 1):
                s = bins[i + 1] - bins[i]
                c.append(bins[i] + (s / 2))

            self.axes.plot(c, n, "ro-")

        self.axes.grid(self.chkShowGrid.isChecked())
        self.axes.set_ylabel(unicode(self.tr("Count")))
        self.axes.set_xlabel(unicode(self.tr("Class")))
        self.figure.autofmt_xdate()
        self.canvas.draw()

    def kmeansCluster(self, layer, distance, number):
        import scipy
        import scipy.cluster.hierarchy as sch
        from scipy.cluster.vq import vq,kmeans,whiten
        import numpy as np

        count = layer.featureCount()
        self.setProgressRange(count)
        points = []
        for f in layer.getFeatures():
            geom = f.geometry()
            x = geom.asPoint().x()
            y = geom.asPoint().y()
            point = []
            point.append(x)
            point.append(y)
            points.append(point)
            self.updateProgress()

        distances = {0:'euclidean', 1:'cityblock', 2:'hamming'}
        disMat = sch.distance.pdist(points, distances.get(distance))#'euclidean''cityblock''hamming''cosine' 
        Z=sch.linkage(disMat,method='average') 
        P=sch.dendrogram(Z)
        cluster= sch.fcluster(Z, t=1, criterion='inconsistent')
        data=whiten(points)
        centroid=kmeans(data, number)[0]
        label=vq(data, centroid)[0]
        return centroid, label

    def addClassField(self, vectorLayer):
        vectorLayerDataProvider = vectorLayer.dataProvider()
        outputFieldName = unicode(self.tr("class"))

        # Create field of not exist
        if vectorLayer.fieldNameIndex(outputFieldName) == -1:
            vectorLayerDataProvider.addAttributes([QgsField(outputFieldName, QVariant.Int)])

        vectorLayer.updateFields()
        vectorLayer.startEditing()
        attrIdx = vectorLayer.fieldNameIndex(outputFieldName)
        features = vectorLayer.getFeatures()

        idx = self.values.tolist()
        i = 0
        for feature in features:
            vectorLayer.changeAttributeValue(feature.id(), attrIdx, int(idx[i]))
            i += 1

        vectorLayer.updateFields()
        vectorLayer.commitChanges()
        self.symbolLayer(vectorLayer)

    def saveAsMap(self, layer):
        reg = QgsMapLayerRegistry.instance()
        i = QImage(QSize(800,800), QImage.Format_ARGB32_Premultiplied)
        c = QColor("white")
        i.fill(c.rgb())
        p = QPainter()
        p.begin(i)
        r = QgsMapRenderer()
        lyrs = reg.mapLayers().keys()
        r.setLayerSet(lyrs)
        rect = QgsRectangle(r.fullExtent())
        rect.scale(1.1)
        r.setExtent(rect)
        r.setOutputSize(i.size(), i.logicalDpiX())
        r.render(p)
        p.end()
        i.save(self.outPath,"jpg")

    # def saveAsMap(self, layer):
    #     i = QImage(QSize(800,800), QImage.Format_ARGB32_Premultiplied)
    #     c = QColor("white")
    #     i.fill(c.rgb())
    #     p = QPainter()
    #     p.begin(i)
    #     p.setRenderHint(QPainter.Antialiasing)
    #     r = QgsMapRenderer()
    #     lyrs = [layer.getLayerID()]
    #     r.setLayerSet(lyrs)
    #     rect = QgsRect(r.fullExtent())
    #     rect.scale(1.1)
    #     r.setExtent(rect)
    #     r.setOutputSize(i.size(), i.logicalDpiX())
    #     r.render(p)
    #     p.end()
    #     i.save(self.outPath,"jpg")

    def symbolLayer(self, layer):
        classField = (
            ("0",0,0,"red"),
            ("1",1,1,"orange"),
            ("2",2,2,"yellow"),
            ("3",3,3,"green"),
            ("4",4,4,"cyan"),
            ("5",5,5,"blue"),
            ("6",6,6,"purple"),
            ("7",7,7,"brown"),
            ("8",8,8,"grey"),
            ("9",9,9,"black"))
        ranges = []
        for label,lower,upper,color in classField:
            sym = QgsSymbolV2.defaultSymbol(layer.geometryType())
            sym.setColor(QColor(color))
            rng = QgsRendererRangeV2(lower, upper, sym, label)
            ranges.append(rng)

        field = "class"
        renderer = QgsGraduatedSymbolRendererV2(field, ranges)
        layer.setRendererV2(renderer)
        layer.triggerRepaint()
        self.saveAsMap(layer) 
Esempio n. 5
0
class InitRose(object):
    #Create a rose diagram
    def __init__(self, plotTarget, barTarget, col=0, row=0):
        # add matplotlib figure to dialog
        self.plotTarget = plotTarget
        self.barTarget = barTarget
        self.col = col
        self.row = row
        self.setupFigure()

    def setupFigure(self):
        self.rosefigure = Figure()
        self.axes = self.rosefigure.add_subplot(
            111, polar=True)  #set up a plot with polar co-ordinates
        self.axes.set_theta_direction(
            -1)  #change the direction of increasing angle to match compass
        self.axes.set_theta_zero_location(
            "N")  #change the O theta position to North
        self.canvas = FigureCanvas(self.rosefigure)
        self.mpltoolbar = NavigationToolbar(self.canvas, self.barTarget)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.plotTarget.addWidget(self.canvas, self.row, self.col)
        self.plotTarget.addWidget(self.mpltoolbar)

        # and configure matplotlib params
        rcParams["font.serif"] = "Verdana, Arial, Liberation Serif"
        rcParams["font.sans-serif"] = "Tahoma, Arial, Liberation Sans"
        rcParams["font.cursive"] = "Courier New, Arial, Liberation Sans"
        rcParams["font.fantasy"] = "Comic Sans MS, Arial, Liberation Sans"
        rcParams["font.monospace"] = "Courier New, Liberation Mono"

    def rosePlotter(self, aziList, title):

        self.axes.set_title(title)
        angle = 15  #the width of the divisions of the rose diagram. later stage this could be set by value in dialog box
        ##get data list
        data = aziList
        #set up bin parameters
        nsection = 360 // angle
        direction = np.linspace(0, 360, nsection, False) / 180 * np.pi
        #print direction
        ##set up list for counting frequency
        frequency = [0] * (nsection)
        ##count up how many in each bin

        for i in data:

            tmp = int(
                (i - (i % angle)) / angle)  ##figure out which bin data belongs
            frequency[tmp] = frequency[tmp] + 1

        awidth = angle / 180.0 * np.pi * np.ones(
            nsection
        )  ## makes an array with nection entries all with the same number representing the angular width

        self.bar = self.axes.bar(direction,
                                 frequency,
                                 width=awidth,
                                 bottom=0.0)
        self.rosefigure.canvas.draw()

    def resetFigure(self):
        #plt.close(self.rosefigure)
        #self.setupFigure()
        try:
            self.bar.remove()
        except:
            pass
        self.rosefigure.canvas.draw()
Esempio n. 6
0
class InitScatter:
    """
    def __init__(self, plotTarget, barTarget):
         # add matplotlib figure to dialog
        self.plotTarget = plotTarget  
        self.barTarget = barTarget
        
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        self.mpltoolbar = NavigationToolbar(self.canvas, self.barTarget)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.plotTarget.addWidget(self.canvas)
        self.plotTarget.addWidget(self.mpltoolbar)

        # and configure matplotlib params
        rcParams["font.serif"] = "Verdana, Arial, Liberation Serif"
        rcParams["font.sans-serif"] = "Tahoma, Arial, Liberation Sans"
        rcParams["font.cursive"] = "Courier New, Arial, Liberation Sans"
        rcParams["font.fantasy"] = "Comic Sans MS, Arial, Liberation Sans"
        rcParams["font.monospace"] = "Courier New, Liberation Mono"
        """

    #this is the fryplot init - will this work for the histogram?
    def __init__(self, plotTarget, barTarget, col=0, row=0):
        # add matplotlib figure to dialog
        self.plotTarget = plotTarget
        self.barTarget = barTarget
        self.col = col
        self.row = row
        self.setupFigure()

    def setupFigure(self):
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)
        self.mpltoolbar = NavigationToolbar(self.canvas, self.barTarget)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction(lstActions[7])
        self.plotTarget.addWidget(self.canvas, self.row, self.col)
        self.plotTarget.addWidget(self.mpltoolbar, self.row + 1, self.col)

        # and configure matplotlib params
        rcParams["font.serif"] = "Verdana, Arial, Liberation Serif"
        rcParams["font.sans-serif"] = "Tahoma, Arial, Liberation Sans"
        rcParams["font.cursive"] = "Courier New, Arial, Liberation Sans"
        rcParams["font.fantasy"] = "Comic Sans MS, Arial, Liberation Sans"
        rcParams["font.monospace"] = "Courier New, Liberation Mono"

    def scatterPlotter(self, listX, listY, title):

        self.axes.clear()
        self.axes.set_title(title, size=9)

        self.scatter = self.axes.scatter(listX, listY, 2)
        self.axes.axis('equal')
        self.axes.grid(b=True)
        self.axes.tick_params(labelsize=4)
        self.canvas.draw()

    def resetFigure(self):
        #plt.close(self.figure)
        #self.setupFigure()
        try:
            self.scatter.remove()
            self.setupFigure()
        except:
            pass
        self.figure.canvas.draw()
Esempio n. 7
0
class calibrlogger(PyQt4.QtGui.QMainWindow, Calibr_Ui_Dialog): # An instance of the class Calibr_Ui_Dialog is created same time as instance of calibrlogger is created

    def __init__(self, parent, settingsdict1={}, obsid=''):
        PyQt4.QtGui.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))#show the user this may take a long time...
        self.obsid = obsid
        self.log_pos = None
        self.y_pos = None
        self.meas_ts = None
        self.head_ts = None
        self.level_masl_ts = None
        self.loggerpos_masl_or_offset_state = 1

        self.settingsdict = settingsdict1
        PyQt4.QtGui.QDialog.__init__(self, parent)        
        self.setAttribute(PyQt4.QtCore.Qt.WA_DeleteOnClose)
        self.setupUi(self) # Required by Qt4 to initialize the UI
        self.setWindowTitle("Calculate water level from logger") # Set the title for the dialog
        self.INFO.setText("Select the observation point with logger data to be adjusted.")
        self.log_calc_manual.setText("<a href=\"https://github.com/jkall/qgis-midvatten-plugin/wiki/4.-Edit-data\">Midvatten manual</a>")
      
        # Create a plot window with one single subplot
        self.calibrplotfigure = plt.figure() 
        self.axes = self.calibrplotfigure.add_subplot( 111 )
        self.canvas = FigureCanvas( self.calibrplotfigure )
        self.mpltoolbar = NavigationToolbar( self.canvas, self.widgetPlot )
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction( lstActions[ 7 ] )
        self.layoutplot.addWidget( self.canvas )
        self.layoutplot.addWidget( self.mpltoolbar )
        self.calibrplotfigure.tight_layout()
        self.show()

        self.cid =[]
                
        self.connect(self.pushButtonSet, PyQt4.QtCore.SIGNAL("clicked()"), self.set_logger_pos)
        self.connect(self.pushButtonAdd, PyQt4.QtCore.SIGNAL("clicked()"), self.add_to_level_masl)
        self.connect(self.pushButtonFrom, PyQt4.QtCore.SIGNAL("clicked()"), self.set_from_date_from_x)
        self.connect(self.pushButtonTo, PyQt4.QtCore.SIGNAL("clicked()"), self.set_to_date_from_x)
        self.connect(self.pushButtonupdateplot, PyQt4.QtCore.SIGNAL("clicked()"), self.update_plot)
        #self.connect(self.loggerpos_masl_or_offset, PyQt4.QtCore.SIGNAL("clicked()"), self.loggerpos_masl_or_offset_change)
        #self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.calibrate_from_plot_selection)
        self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_old_level)
        self.connect(self.pushButtonMpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_new_level)
        self.pushButtonMpos.setEnabled(False)
        self.connect(self.pushButtonCalcBestFit, PyQt4.QtCore.SIGNAL("clicked()"), self.logger_pos_best_fit)
        self.connect(self.pushButtonCalcBestFit2, PyQt4.QtCore.SIGNAL("clicked()"), self.level_masl_best_fit)

        self.connect(self.pushButton_delete_logger, PyQt4.QtCore.SIGNAL("clicked()"), lambda: self.delete_selected_range(u'w_levels_logger'))

        self.get_search_radius()

        # Populate combobox with obsid from table w_levels_logger
        self.load_obsid_from_db()

        PyQt4.QtGui.QApplication.restoreOverrideCursor()#now this long process is done and the cursor is back as normal

    def load_obsid_from_db(self):
        print ('am here')#debug
        self.combobox_obsid.clear()
        myconnection = utils.dbconnection()
        if myconnection.connect2db() == True:
            print('connected')#debug
            # skapa en cursor
            curs = myconnection.conn.cursor()
            rs=curs.execute("""select distinct obsid from w_levels_logger order by obsid""")
            self.combobox_obsid.addItem('')
            for row in curs:
                print(row[0])#debug
                self.combobox_obsid.addItem(row[0])
            rs.close()
            myconnection.closedb()

    def load_obsid_and_init(self):
        """ Checks the current obsid and reloads all ts.
        :return: obsid

        Info: Before, some time series was only reloaded when the obsid was changed, but this caused a problem if the
        data was changed in the background in for example spatialite gui. Now all time series are reloaded always.
        It's rather fast anyway.
        """
        obsid = unicode(self.combobox_obsid.currentText())
        if not obsid:
            utils.pop_up_info("ERROR: no obsid is chosen")
            return None

        meas_sql = r"""SELECT date_time, level_masl FROM w_levels WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.meas_ts = self.sql_into_recarray(meas_sql)
        head_sql = r"""SELECT date_time as 'date [datetime]', head_cm / 100 FROM w_levels_logger WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.head_ts = self.sql_into_recarray(head_sql)
        self.obsid = obsid
        level_masl_ts_sql = r"""SELECT date_time as 'date [datetime]', level_masl FROM w_levels_logger WHERE obsid = '""" + self.obsid + """' ORDER BY date_time"""
        self.level_masl_ts = self.sql_into_recarray(level_masl_ts_sql)
        return obsid

    def getlastcalibration(self):
        obsid = self.load_obsid_and_init()
        if not obsid=='':
            sql = """SELECT MAX(date_time), loggerpos FROM (SELECT date_time, (level_masl - (head_cm/100)) as loggerpos FROM w_levels_logger WHERE level_masl > -990 AND obsid = '"""
            sql += obsid
            sql += """')"""
            self.lastcalibr = utils.sql_load_fr_db(sql)[1]
            if self.lastcalibr[0][1] and self.lastcalibr[0][0]:
                text = """Last pos. for logger in """
                text += obsid
                text += """ was """ + str(self.lastcalibr[0][1]) + """ masl at """ +  str(self.lastcalibr[0][0])
            else:
                text = """There is no earlier known position for the logger in """ + unicode(self.combobox_obsid.currentText())#self.obsid[0]
            self.INFO.setText(text)

    def set_logger_pos(self):
        self.loggerpos_masl_or_offset_state = 1
        obsid = self.load_obsid_and_init()
        if not self.LoggerPos.text() == '':
            self.calibrate()
        self.update_plot()

    def add_to_level_masl(self):
        self.loggerpos_masl_or_offset_state = 0
        obsid = self.load_obsid_and_init()
        if not self.Add2Levelmasl.text() == '':
            self.calibrate()
        self.update_plot()

    def calibrate(self):
        self.calib_help.setText("Calibrating")
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        obsid = self.load_obsid_and_init()
        if not obsid=='':        
            sanity1sql = """select count(obsid) from w_levels_logger where obsid = '""" +  obsid[0] + """'"""
            sanity2sql = """select count(obsid) from w_levels_logger where head_cm not null and head_cm !='' and obsid = '""" +  obsid[0] + """'"""
            if utils.sql_load_fr_db(sanity1sql)[1] == utils.sql_load_fr_db(sanity2sql)[1]: # This must only be done if head_cm exists for all data
                fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
                to_d_t = self.ToDateTime.dateTime().toPyDateTime()

                if self.loggerpos_masl_or_offset_state == 1:
                    self.update_level_masl_from_head(obsid, fr_d_t, to_d_t, self.LoggerPos.text())
                else:
                    self.update_level_masl_from_level_masl(obsid, fr_d_t, to_d_t, self.Add2Levelmasl.text())

                self.getlastcalibration()
            else:
                utils.pop_up_info("Calibration aborted!!\nThere must not be empty cells or\nnull values in the 'head_cm' column!")
        else:
            self.INFO.setText("Select the observation point with logger data to be calibrated.")
        self.calib_help.setText("")
        PyQt4.QtGui.QApplication.restoreOverrideCursor()

    def update_level_masl_from_level_masl(self, obsid, fr_d_t, to_d_t, newzref):
        """ Updates the level masl using newzref
        :param obsid: (str) The obsid
        :param fr_d_t: (datetime) start of calibration
        :param to_d_t: (datetime) end of calibration
        :param newzref: (int/float/str [m]) The correction that should be made against the head [m]
        :return: None
        """
        sql =r"""UPDATE w_levels_logger SET level_masl = """
        sql += str(newzref)
        sql += """ + level_masl WHERE obsid = '"""
        sql += obsid
        # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first.
        sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """
        sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """
        sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ """
        dummy = utils.sql_alter_db(sql)

    def update_level_masl_from_head(self, obsid, fr_d_t, to_d_t, newzref):
        """ Updates the level masl using newzref
        :param obsid: (str) The obsid
        :param fr_d_t: (datetime) start of calibration
        :param to_d_t: (datetime) end of calibration
        :param newzref: (int/float/str [m]) The correction that should be made against the head [m]
        :return: None
        """
        sql =r"""UPDATE w_levels_logger SET level_masl = """
        sql += str(newzref)
        sql += """ + head_cm / 100 WHERE obsid = '"""
        sql += obsid
        # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first (but now we changed to > but kept .total_seconds())
        sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """
        sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """
        sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ """
        dummy = utils.sql_alter_db(sql)

    def sql_into_recarray(self, sql):
        """ Converts and runs an sql-string and turns the answer into an np.recarray and returns it""" 
        my_format = [('date_time', datetime.datetime), ('values', float)] #Define (with help from function datetime) a good format for numpy array     
        recs = utils.sql_load_fr_db(sql)[1]
        table = np.array(recs, dtype=my_format)  #NDARRAY
        table2=table.view(np.recarray)   # RECARRAY   Makes the two columns inte callable objects, i.e. write table2.values 
        return table2        

    def update_plot(self):
        """ Plots self.level_masl_ts, self.meas_ts and maybe self.head_ts """
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Updating plot")
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        obsid = self.load_obsid_and_init()
        if obsid == None:
            PyQt4.QtGui.QApplication.restoreOverrideCursor()
            self.calib_help.setText("")
            return
        self.axes.clear()
        
        p=[None]*2 # List for plot objects
    
        # Load manual reading (full time series) for the obsid
        self.plot_recarray(self.axes, self.meas_ts, obsid, 'o-', 10)
        
        # Load Loggerlevels (full time series) for the obsid
        if self.loggerLineNodes.isChecked():
            logger_line_style = '.-'
        else:
            logger_line_style = '-'                
        self.plot_recarray(self.axes, self.level_masl_ts, obsid + unicode(' logger', 'utf-8'), logger_line_style, 10)

        #Plot the original head_cm
        if self.plot_logger_head.isChecked():
            self.plot_recarray(self.axes, self.head_ts, obsid + unicode(' original logger head', 'utf-8'), logger_line_style, 10)

        """ Finish plot """
        self.axes.grid(True)
        self.axes.yaxis.set_major_formatter(tick.ScalarFormatter(useOffset=False, useMathText=False))
        self.calibrplotfigure.autofmt_xdate()
        self.axes.set_ylabel(unicode('Level (masl)', 'utf-8'))  #This is the method that accepts even national characters ('åäö') in matplotlib axes labels
        self.axes.set_title(unicode('Plot for ', 'utf-8') + str(obsid))  #This is the method that accepts even national characters ('åäö') in matplotlib axes labels
        for label in self.axes.xaxis.get_ticklabels():
            label.set_fontsize(10)
        for label in self.axes.yaxis.get_ticklabels():
            label.set_fontsize(10)
        #plt.show()
        self.calibrplotfigure.tight_layout()
        self.canvas.draw()
        plt.close(self.calibrplotfigure)#this closes reference to self.calibrplotfigure
        PyQt4.QtGui.QApplication.restoreOverrideCursor()
        self.calib_help.setText("")

        self.getlastcalibration()

    def plot_recarray(self, axes, a_recarray, lable, line_style, picker=10):
        """ Plots a recarray to the supplied axes object """
        # Get help from function datestr2num to get date and time into float
        myTimestring = [a_recarray.date_time[idx] for idx in xrange(len(a_recarray))]
        numtime=datestr2num(myTimestring)  #conv list of strings to numpy.ndarray of floats
        axes.plot_date(numtime, a_recarray.values, line_style, label=lable, picker=picker)

    def set_from_date_from_x(self):
        """ Used to set the self.FromDateTime by clicking on a line node in the plot self.canvas """
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Select a node to use as \"from\"")
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()   
        self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.FromDateTime)))

    def set_to_date_from_x(self):
        """ Used to set the self.ToDateTime by clicking on a line node in the plot self.canvas """    
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Select a node to use as \"to\"")
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()   
        self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.ToDateTime)))

    def set_date_from_x_onclick(self, event, date_holder):
        """ Sets the date_holder to a date from a line node closest to the pick event

            date_holder: a QDateTimeEdit object.
        """
        found_date = utils.find_nearest_date_from_event(event)
        date_holder.setDateTime(found_date)           
        self.reset_plot_selects_and_calib_help()
    
    def reset_plot_selects_and_calib_help(self):
        """ Reset self.cid and self.calib_help """
        self.reset_cid()
        self.log_pos = None
        self.y_pos = None
        self.calib_help.setText("")

    def reset_cid(self):
        """ Resets self.cid to an empty list and disconnects unused events """
        for x in self.cid:
            self.canvas.mpl_disconnect(x)
        self.cid = []

    def catch_old_level(self):
        """Part of adjustment method 3. adjust level_masl by clicking in plot.
        this part selects a line node and a y-position on the plot"""
        #Run init to make sure self.meas_ts and self.head_ts is updated for the current obsid.           
        self.load_obsid_and_init()
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()

        self.calib_help.setText("Select a logger node.")
        self.cid.append(self.canvas.mpl_connect('pick_event', self.set_log_pos_from_node_date_click))
            
    def catch_new_level(self):
        """ Part of adjustment method 3. adjust level_masl by clicking in plot.
        this part selects a y-position from the plot (normally user would select a manual measurement)."""
        if self.log_pos is not None:
            self.calib_help.setText("Select a y position to move to.")
            self.cid.append(self.canvas.mpl_connect('button_press_event', self.set_y_pos_from_y_click))
            self.calib_help.setText("")
        else:
            self.calib_help.setText("Something wrong, click \"Current\" and try again.")

    def calculate_offset(self):
        """ Part of adjustment method 3. adjust level_masl by clicking in plot.
        this method extracts the head from head_ts with the same date as the line node.
            4. Calculating y-position - head (or level_masl) and setting self.LoggerPos.
            5. Run calibration.
        """            
        if self.log_pos is not None and self.y_pos is not None:
            PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

            logger_ts = self.level_masl_ts
            
            y_pos = self.y_pos
            log_pos = self.log_pos
            self.y_pos = None
            self.log_pos = None
            log_pos_date = datestring_to_date(log_pos).replace(tzinfo=None)
            logger_value = None

            #Get the value for the selected node
            for raw_date, logger_value in logger_ts:
                date = datestring_to_date(raw_date).replace(tzinfo=None)
                if date == log_pos_date:
                    break

            if logger_value is None:
                utils.pop_up_info("No connection between level_masl dates and logger date could be made!\nTry again or choose a new logger line node!")
            else:
                self.Add2Levelmasl.setText(str(float(y_pos) - float(logger_value)))

                PyQt4.QtGui.QApplication.restoreOverrideCursor()

        self.pushButtonMpos.setEnabled(False)
        
    def set_log_pos_from_node_date_click(self, event):
        """ Sets self.log_pos variable to the date (x-axis) from the node nearest the pick event """
        found_date = utils.find_nearest_date_from_event(event)
        #self.calib_help.setText("Logger node " + str(found_date) + " selected, click button \"Calibrate by selection in plot\" again.")
        self.calib_help.setText("Logger node " + str(found_date) + " selected, click \"new\" and select new level.")
        self.log_pos = found_date
        self.reset_cid()
        self.pushButtonMpos.setEnabled(True)
 
    def set_y_pos_from_y_click(self, event):
        """ Sets the self.y_pos variable to the y value of the click event """
        self.y_pos = event.ydata
        #self.calib_help.setText("Y position set, click button \"Calibrate by selection in plot\" again for calibration.")
        self.calculate_offset()
        self.calib_help.setText("Offset is calculated, now click \"add\".")
        self.reset_cid()

    def logger_pos_best_fit(self):
        self.loggerpos_masl_or_offset_state = 1
        self.calc_best_fit()

    def level_masl_best_fit(self):
        self.loggerpos_masl_or_offset_state = 0
        self.calc_best_fit()
        
    def calc_best_fit(self):
        """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts
        
            First matches measurements from self.meas_ts to logger values from
            self.head_ts. This is done by making a mean of all logger values inside
            self.meas_ts date - search_radius and self.meas_ts date + search_radius.
            (this could probably be change to get only the closest logger value
            inside the search_radius instead)
            (search_radius is gotten from self.get_search_radius())
            
            Then calculates the mean of all matches and set to self.LoggerPos.
        """
        obsid = self.load_obsid_and_init()
        self.reset_plot_selects_and_calib_help()
        search_radius = self.get_search_radius()
        if self.loggerpos_masl_or_offset_state == 1:# UPDATE TO RELEVANT TEXT
            logger_ts = self.head_ts
            text_field = self.LoggerPos
            calib_func = self.set_logger_pos
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between head_cm and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        else:# UPDATE TO RELEVANT TEXT
            logger_ts = self.level_masl_ts
            text_field = self.Add2Levelmasl
            calib_func = self.add_to_level_masl
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between level_masl and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        if really_calibrate_question.result == 0: # if the user wants to abort
            return

        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

        coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, search_radius)
        if not coupled_vals:
            utils.pop_up_info("There was no matched measurements or logger values inside the chosen period.\n Try to increase the search radius!")
        else:
            text_field.setText(str(utils.calc_mean_diff(coupled_vals)))
            calib_func()

        PyQt4.QtGui.QApplication.restoreOverrideCursor()
     
    def match_ts_values(self, meas_ts, logger_ts, search_radius_tuple):
        """ Matches two timeseries values for shared timesteps 
        
            For every measurement point, a mean of logger values inside 
            measurementpoint + x minutes to measurementpoint - x minutes
            is coupled together.

            At the first used measurement, only logger values greater than
            the set start date is used.
            At the last measurement, only logger values lesser than the set end
            date is used.
            This is done so that values from another logger reposition is not
            mixed with the chosen logger positioning. (Hard to explain).
        """
        coupled_vals = []
        
        #Get the search radius, default to 10 minutes
        search_radius = int(search_radius_tuple[0])
        search_radius_period = search_radius_tuple[1]
  
        logger_gen = utils.ts_gen(logger_ts)
        try:
            l = next(logger_gen)
        except StopIteration:
            return None
        log_vals = []

        all_done = False
        #The .replace(tzinfo=None) is used to remove info about timezone. Needed for the comparisons. This should not be a problem though as the date scale in the plot is based on the dates from the database. 
        outer_begin = self.FromDateTime.dateTime().toPyDateTime().replace(tzinfo=None)
        outer_end = self.ToDateTime.dateTime().toPyDateTime().replace(tzinfo=None)
        logger_step = datestring_to_date(l[0]).replace(tzinfo=None)
        for m in meas_ts:
            if logger_step is None:
                break
            meas_step = datestring_to_date(m[0]).replace(tzinfo=None)

            step_begin = dateshift(meas_step, -search_radius, search_radius_period)
            step_end = dateshift(meas_step, search_radius, search_radius_period)

            if step_end < outer_begin:
                continue
            if step_begin > outer_end:
                break

            #Skip logger steps that are earlier than the chosen begin date or are not inside the measurement period.
            while logger_step < step_begin or logger_step < outer_begin:
                try:
                    l = next(logger_gen)
                except StopIteration:
                    all_done = True
                    break
                logger_step = datestring_to_date(l[0]).replace(tzinfo=None)

            log_vals = []

            while logger_step is not None and step_begin <= logger_step <= step_end and outer_begin <= logger_step <= outer_end:
                if not math.isnan(float(l[1])) or l[1] in ('nan', 'NULL'):
                    log_vals.append(float(l[1]))
                try:
                    l = next(logger_gen)
                except StopIteration:
                    all_done = True
                    break
                logger_step = datestring_to_date(l[0]).replace(tzinfo=None)                     

            if log_vals:
                mean = np.mean(log_vals)
                if not math.isnan(mean):
                    coupled_vals.append((m[1], mean))
            if all_done:
                break
        return coupled_vals
                      
    def get_search_radius(self):
        """ Get the period search radius, default to 10 minutes """
        if not self.bestFitSearchRadius.text():
            search_radius = '10 minutes'
            self.bestFitSearchRadius.setText(search_radius)
        else:
            search_radius = self.bestFitSearchRadius.text()

        search_radius_splitted = search_radius.split()
        if len(search_radius_splitted) != 2:
            utils.pop_up_info("Must write time resolution also, ex. 10 minutes")
        return tuple(search_radius_splitted)

    def deactivate_pan_zoom(self):
        """ Deactivates the NavigationToolbar pan or zoom feature if they are currently active """
        if self.mpltoolbar._active == "PAN":
            self.mpltoolbar.pan()
        elif self.mpltoolbar._active == "ZOOM":
            self.mpltoolbar.zoom()

    def delete_selected_range(self, table_name):
        """ Deletes the current selected range from the database from w_levels_logger
        :return: De
        """
        current_loaded_obsid = self.obsid
        selected_obsid = self.load_obsid_and_init()
        if current_loaded_obsid != selected_obsid:
            utils.pop_up_info("Error!\n The obsid selection has been changed but the plot has not been updated. No deletion done.\nUpdating plot.")
            self.update_plot()
            return
        elif selected_obsid is None:
            utils.pop_up_info("Error!\n No obsid was selected. No deletion done.\nUpdating plot.")
            self.update_plot()
            return

        fr_d_t = str((self.FromDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())
        to_d_t = str((self.ToDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())

        sql_list = []
        sql_list.append(r"""delete from "%s" """%table_name)
        sql_list.append(r"""where obsid = '%s' """%selected_obsid)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" > '%s' """%fr_d_t)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" < '%s' """%to_d_t)
        sql = ''.join(sql_list)

        really_delete = utils.askuser("YesNo", "Do you want to delete the period " +
                                      str(self.FromDateTime.dateTime().toPyDateTime()) + " to " +
                                      str(self.ToDateTime.dateTime().toPyDateTime()) +
                                      " for obsid " + selected_obsid + " from table " + table_name + "?").result
        if really_delete:
            utils.sql_alter_db(sql)
            self.update_plot()
Esempio n. 8
0
class plotsqlitewindow(QtGui.QMainWindow, customplot_ui_class):
    def __init__(self, parent, msettings):#, parent as second arg?
        self.ms = msettings
        self.ms.loadSettings()
        QtGui.QDialog.__init__(self, parent)        
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setupUi( self )#due to initialisation of Ui_MainWindow instance
        self.initUI()
        self.LoadTablesFromDB()
        self.LastSelections()#fill comboboxes etc with last selected values
        #on close:
        #del self.axes.collections[:]#this should delete all plot objects related to axes and hence not intefere with following tsplots
        self.drawn = False
        
    def initUI(self):
        self.table_ComboBox_1.clear()  
        self.table_ComboBox_2.clear()  
        self.table_ComboBox_3.clear()  
        for i in range (1,3):
            self.clearthings(1)
        # function partial due to problems with currentindexChanged and Combobox
        #self.connect(self.table_ComboBox_1, QtCore.SIGNAL("currentIndexChanged(int)"), partial(self.Table1Changed))#currentIndexChanged caused unnecessary signals when scrolling in combobox
        self.connect(self.table_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Table1Changed))  
        self.connect(self.Filter1_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_1Changed))
        #self.connect(self.Filter1_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.FilterChanged(1,1)))
        self.connect(self.Filter2_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_1Changed)) 
        self.connect(self.table_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Table2Changed)) 
        self.connect(self.Filter1_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_2Changed))
        self.connect(self.Filter2_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_2Changed)) 
        self.connect(self.table_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Table3Changed)) 
        self.connect(self.Filter1_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_3Changed))
        self.connect(self.Filter2_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_3Changed)) 
        self.PlotChart_QPushButton.clicked.connect(self.drawPlot)
        self.Redraw_pushButton.clicked.connect( self.refreshPlot )
        
        # Create a plot window with one single subplot
        self.custplotfigure = plt.figure() 
        self.axes = self.custplotfigure.add_subplot( 111 )
        self.canvas = FigureCanvas( self.custplotfigure )
        self.mpltoolbar = NavigationToolbar( self.canvas, self.widgetPlot)
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction( lstActions[ 7 ] )
        self.layoutplot.addWidget( self.canvas )
        self.layoutplot.addWidget( self.mpltoolbar )

        #Validator for QlineEdit that should contain only floats, any number of decimals with either point(.) or comma(,) as a decimal separater
        regexp = QtCore.QRegExp('[+-]?\\d*[\\.,]?\\d+') 
        validator = QtGui.QRegExpValidator(regexp)
        self.LineEditFactor1.setValidator(validator)
        self.LineEditFactor2.setValidator(validator)
        self.LineEditFactor3.setValidator(validator)
        self.LineEditOffset1.setValidator(validator)
        self.LineEditOffset2.setValidator(validator)
        self.LineEditOffset3.setValidator(validator)
        
        self.show()

    def calc_frequency(self,table2):
        freqs = np.zeros(len(table2.values),dtype=float)
        for j, row in enumerate(table2):                
            if j>0:#we can not calculate frequency for first row
                try:
                    diff = (table2.values[j] - table2.values[j-1])
                    """ Get help from function datestr2num to get date and time into float"""
                    delta_time = 24*3600*(datestr2num(table2.date_time[j]) - datestr2num(table2.date_time[j-1]))#convert to seconds since numtime is days
                except:
                    pass #just skip inaccurate data values and use previous frequency
                freqs[j] = diff/delta_time
        freqs[0]=freqs[1]#assuming start frequency to get a nicer plot

        return freqs 
        
    def drawPlot(self):
        QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))#show the user this may take a long time...

        self.axes.clear()
        self.axes.legend_ = None
        My_format = [('date_time', datetime.datetime), ('values', float)] #Define (with help from function datetime) a good format for numpy array
        
        myconnection = utils.dbconnection()
        myconnection.connect2db()
        curs = myconnection.conn.cursor()

        i = 0
        nop=0# nop=number of plots
        self.p=[]
        self.plabels=[]
                
        if not (self.table_ComboBox_1.currentText() == '' or self.table_ComboBox_1.currentText()==' ') and not (self.xcol_ComboBox_1.currentText()== '' or self.xcol_ComboBox_1.currentText()==' ') and not (self.ycol_ComboBox_1.currentText()== '' or self.ycol_ComboBox_1.currentText()==' '): #if anything is to be plotted from tab 1
            self.ms.settingsdict['custplot_maxtstep'] = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable1='y'
            filter1 = unicode(self.Filter1_ComboBox_1.currentText())
            filter1list = []
            filter2list = []
            filter1list = self.Filter1_QListWidget_1.selectedItems()
            filter2 = unicode(self.Filter2_ComboBox_1.currentText())
            filter2list= self.Filter2_QListWidget_1.selectedItems()
            nop += max(len(filter1list),1)*max(len(filter2list),1)
            #self.p= [None]*nop#list for plot objects
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            try:
                factor1 = float(self.LineEditFactor1.text().replace(',','.'))
            except ValueError:
                factor1 = 1.0
            try:
                offset1 = float(self.LineEditOffset1.text().replace(',','.'))
            except ValueError:
                offset1 = 0.0

            remove_mean1 = self.checkBox_remove_mean1.isChecked()

            while i < len(self.p):
                if not (filter1 == '' or filter1==' ' or filter1list==[]) and not (filter2== '' or filter2==' ' or filter2list==[]):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + unicode(self.xcol_ComboBox_1.currentText()) + """, """ + unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' and """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_1.currentText())
                            self.plabels[i] = unicode(item1.text()) + """, """ + unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText(), factor1, offset1, remove_mean1)
                            i += 1
                elif not (filter1 == '' or filter1==' ' or filter1list==[]):
                    for item1 in filter1list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_1.currentText()) + """, """ + unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' order by """ + unicode(self.xcol_ComboBox_1.currentText())
                        self.plabels[i] = unicode(item1.text()) 
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText(), factor1, offset1, remove_mean1)
                        i += 1
                elif not (filter2 == '' or filter2==' ' or filter2list==[]):
                    for item2 in filter2list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_1.currentText()) + """, """ + unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_1.currentText())
                        self.plabels[i] = unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText(), factor1, offset1, remove_mean1)
                        i += 1            
                else:
                    sql = r""" select """ + unicode(self.xcol_ComboBox_1.currentText()) + """, """ + unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + unicode(self.table_ComboBox_1.currentText()) + """ order by """ + unicode(self.xcol_ComboBox_1.currentText())
                    self.plabels[i] = unicode(self.ycol_ComboBox_1.currentText())+""", """+unicode(self.table_ComboBox_1.currentText())
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText(), factor1, offset1, remove_mean1)
                    i += 1

        if not (self.table_ComboBox_2.currentText() == '' or self.table_ComboBox_2.currentText()==' ') and not (self.xcol_ComboBox_2.currentText()== '' or self.xcol_ComboBox_2.currentText()==' ') and not (self.ycol_ComboBox_2.currentText()== '' or self.ycol_ComboBox_2.currentText()==' '):#if anything is to be plotted from tab 2
            self.ms.settingsdict['custplot_maxtstep'] = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable2='y'
            filter1 = unicode(self.Filter1_ComboBox_2.currentText())
            filter1list = []
            filter2list = []
            filter1list = self.Filter1_QListWidget_2.selectedItems()
            filter2 = unicode(self.Filter2_ComboBox_2.currentText())
            filter2list= self.Filter2_QListWidget_2.selectedItems()
            nop =+ max(len(filter1list),1)*max(len(filter2list),1)
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            try:
                factor2 = float(self.LineEditFactor2.text().replace(',','.'))
            except ValueError:
                factor2 = 1.0
            try:
                offset2 = float(self.LineEditOffset2.text().replace(',','.'))
            except ValueError:
                offset2 = 0.0

            remove_mean2 = self.checkBox_remove_mean2.isChecked()

            while i < len(self.p):
                if not (filter1 == '' or filter1==' ' or filter1list==[]) and not (filter2== '' or filter2==' ' or filter2list==[]):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + unicode(self.xcol_ComboBox_2.currentText()) + """, """ + unicode(self.ycol_ComboBox_2.currentText()) + """ from """ + unicode(self.table_ComboBox_2.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' and """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_2.currentText())
                            self.plabels[i] = unicode(item1.text()) + """, """ + unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText(), factor2, offset2, remove_mean2)
                            i += 1
                elif not (filter1 == '' or filter1==' ' or filter1list==[]):
                    for item1 in filter1list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_2.currentText()) + """, """ + unicode(self.ycol_ComboBox_2.currentText()) + """ from """ + unicode(self.table_ComboBox_2.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' order by """ + unicode(self.xcol_ComboBox_2.currentText())
                        self.plabels[i] = unicode(item1.text()) 
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText(), factor2, offset2, remove_mean2)
                        i += 1
                elif not (filter2 == '' or filter2==' ' or filter2list==[]):
                    for item2 in filter2list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_2.currentText()) + """, """ + unicode(self.ycol_ComboBox_2.currentText()) + """ from """ + unicode(self.table_ComboBox_2.currentText()) + """ where """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_2.currentText())
                        self.plabels[i] = unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText(), factor2, offset2, remove_mean2)
                        i += 1            
                else:
                    sql = r""" select """ + unicode(self.xcol_ComboBox_2.currentText()) + """, """ + unicode(self.ycol_ComboBox_2.currentText()) + """ from """ + unicode(self.table_ComboBox_2.currentText()) + """ order by """ + unicode(self.xcol_ComboBox_2.currentText())
                    self.plabels[i] = unicode(self.ycol2)+""", """+unicode(self.table_ComboBox_2.currentText())
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText(), factor2, offset2, remove_mean2)
                    i += 1
            
        if not (self.table_ComboBox_3.currentText() == '' or self.table_ComboBox_3.currentText()==' ') and not (self.xcol_ComboBox_3.currentText()== '' or self.xcol_ComboBox_3.currentText()==' ') and not (self.ycol_ComboBox_3.currentText()== '' or self.ycol_ComboBox_3.currentText()==' '):#if anything is to be plotted from tab 3
            self.ms.settingsdict['custplot_maxtstep'] = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable3='y'
            filter1 = unicode(self.Filter1_ComboBox_3.currentText())
            filter1list = []
            filter2list = []
            filter1list = self.Filter1_QListWidget_3.selectedItems()
            filter2 = unicode(self.Filter2_ComboBox_3.currentText())
            filter2list= self.Filter2_QListWidget_3.selectedItems()
            nop =+ max(len(filter1list),1)*max(len(filter2list),1)
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            try:
                factor3 = float(self.LineEditFactor3.text().replace(',','.'))
            except ValueError:
                factor3 = 1.0
            try:
                offset3 = float(self.LineEditOffset3.text().replace(',','.'))
            except ValueError:
                offset3 = 0.0

            remove_mean3 = self.checkBox_remove_mean3.isChecked()

            while i < len(self.p):
                if not (filter1 == '' or filter1==' ' or filter1list==[]) and not (filter2== '' or filter2==' ' or filter2list==[]):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + unicode(self.xcol_ComboBox_3.currentText()) + """, """ + unicode(self.ycol_ComboBox_3.currentText()) + """ from """ + unicode(self.table_ComboBox_3.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' and """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_3.currentText())
                            self.plabels[i] = unicode(item1.text()) + """, """ + unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText(), factor3, offset3, remove_mean3)
                            i += 1
                elif not (filter1 == '' or filter1==' ' or filter1list==[]):
                    for item1 in filter1list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_3.currentText()) + """, """ + unicode(self.ycol_ComboBox_3.currentText()) + """ from """ + unicode(self.table_ComboBox_3.currentText()) + """ where """ + filter1 + """='""" + unicode(item1.text())+ """' order by """ + unicode(self.xcol_ComboBox_3.currentText())
                        self.plabels[i] = unicode(item1.text()) 
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText(), factor3, offset3, remove_mean3)
                        i += 1
                elif not (filter2 == '' or filter2==' ' or filter2list==[]):
                    for item2 in filter2list:
                        sql = r""" select """ + unicode(self.xcol_ComboBox_3.currentText()) + """, """ + unicode(self.ycol_ComboBox_3.currentText()) + """ from """ + unicode(self.table_ComboBox_3.currentText()) + """ where """ + filter2 + """='""" + unicode(item2.text())+ """' order by """ + unicode(self.xcol_ComboBox_3.currentText())
                        self.plabels[i] = unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText(), factor3, offset3, remove_mean3)
                        i += 1            
                else:
                    sql = r""" select """ + unicode(self.xcol_ComboBox_3.currentText()) + """, """ + unicode(self.ycol_ComboBox_3.currentText()) + """ from """ + unicode(self.table_ComboBox_3.currentText()) + """ order by """ + unicode(self.xcol_ComboBox_3.currentText())
                    self.plabels[i] = unicode(self.ycol_ComboBox_3.currentText())+""", """+unicode(self.table_ComboBox_3.currentText())
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText(), factor3, offset3, remove_mean3)
                    i += 1

        #rs.close() # close the cursor
        myconnection.closedb()  # close the database

        self.xaxis_formatters = (self.axes.xaxis.get_major_formatter(), self.axes.xaxis.get_major_locator())

        self.axes.set_title(self.ms.settingsdict['custplot_title'])
        self.axes.set_xlabel(self.ms.settingsdict['custplot_xtitle'])
        self.axes.set_ylabel(self.ms.settingsdict['custplot_ytitle'])

        self.drawn = True

        self.refreshPlot()

        QtGui.QApplication.restoreOverrideCursor()#now this long process is done and the cursor is back as normal

    def createsingleplotobject(self,sql,i,My_format,curs,plottype='line', factor=1.0, offset=0.0, remove_mean=False):
        rs = curs.execute(sql) #Send SQL-syntax to cursor
        recs = rs.fetchall()  # All data are stored in recs
        # late fix for xy-plots

        #Transform data to a numpy.recarray
        try:
            table = np.array(recs, dtype=My_format)  #NDARRAY
            table2=table.view(np.recarray)   # RECARRAY transform the 2 cols into callable objects
            FlagTimeXY = 'time'
            myTimestring = list(table2.date_time)
            numtime=datestr2num(myTimestring)  #conv list of strings to numpy.ndarray of floats
        except Exception, e:
            utils.MessagebarAndLog.info(log_msg=u"Customplot, transforming to recarray with date_time as x-axis failed, msg: " + utils.returnunicode(str(e)))
            table = np.array(recs, dtype=[('numx', float), ('values', float)])  #NDARRAY #define a format for xy-plot (to use if not datetime on x-axis)

            table2=table.view(np.recarray)   # RECARRAY transform the 2 cols into callable objects
            FlagTimeXY = 'XY'
            numtime = list(table2.numx)

        # from version 0.2 there is a possibility to make discontinuous plot if timestep bigger than maxtstep
        if self.spnmaxtstep.value() > 0: # if user selected a time step bigger than zero than thre may be discontinuous plots
            pos = np.where(np.abs(np.diff(numtime)) >= self.spnmaxtstep.value())[0]
            numtime[pos] = np.nan
            table2.values[pos] = np.nan

        if plottype == "marker":
            MarkVar = 'o'  
        elif plottype in ("line","frequency"):
            MarkVar = '-'  
        elif plottype  == "line and cross":
            MarkVar = '+-'  
        else:
            MarkVar = 'o-'

        if FlagTimeXY == "time" and plottype == "frequency":
            table2.values[:] = self.calc_frequency(table2)[:]

        if remove_mean:
            table2.values[:] = utils.remove_mean_from_nparray(table2.values)[:]

        table2.values[:] = utils.scale_nparray(table2.values, factor, offset)[:]


        if FlagTimeXY == "time" and plottype == "step-pre":
            self.p[i], = self.axes.plot_date(numtime, table2.values, drawstyle='steps-pre', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i])# 'steps-pre' best for precipitation and flowmeters, optional types are 'steps', 'steps-mid', 'steps-post'
        elif FlagTimeXY == "time" and plottype == "step-post":
            self.p[i], = self.axes.plot_date(numtime, table2.values, drawstyle='steps-post', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i])
        elif FlagTimeXY == "time" and plottype == "line and cross":
            self.p[i], = self.axes.plot_date(numtime, table2.values,  MarkVar,markersize = 6, label=self.plabels[i])
        elif FlagTimeXY == "time" and plottype == "frequency":
            try:
                self.p[i], = self.axes.plot_date(numtime, table2.values,  MarkVar,markersize = 6, label='frequency '+str(self.plabels[i]))
                self.plabels[i]='frequency '+str(self.plabels[i])
            except:
                self.p[i], = self.axes.plot_date(np.array([]),np.array([]),  MarkVar,markersize = 6, label='frequency '+str(self.plabels[i]))
                self.plabels[i]='frequency '+str(self.plabels[i])
        elif FlagTimeXY == "time":
            self.p[i], = self.axes.plot_date(numtime, table2.values,  MarkVar,label=self.plabels[i])
        elif FlagTimeXY == "XY" and plottype == "step-pre":
            self.p[i], = self.axes.plot(numtime, table2.values, drawstyle='steps-pre', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i]) 
        elif FlagTimeXY == "XY" and plottype == "step-post":
            self.p[i], = self.axes.plot(numtime, table2.values, drawstyle='steps-post', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i]) 
        elif FlagTimeXY == "XY" and plottype == "line and cross":
            self.p[i], = self.axes.plot(numtime, table2.values,  MarkVar,markersize = 6, label=self.plabels[i])
        else: 
            self.p[i], = self.axes.plot(numtime, table2.values,  MarkVar,label=self.plabels[i])
Esempio n. 9
0
class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent = None):
        #QtGui.QMainWindow.__init__(self, parent)#the line below is for some reason preferred
        super(MainWindow, self).__init__(parent)#for some reason this is supposed to be better than line above
        #QDialog.__init__( self ) #if not working with an application with mainwindow
        #self.iface = iface

        #self=Ui_MainWindow()#new
                
        self.setupUi( self )#due to initialisation of Ui_MainWindow instance
        self.initUI()
        self.maxtstep = 0
        #self.database = ''
        #self.table1 = ''
        #self.database_pyqt4provider = QtSql.QSqlDatabase.addDatabase("QSQLITE","db1")
        
    def initUI(self):
        self.table_ComboBox_1.clear()  
        self.table_ComboBox_2.clear()  
        self.table_ComboBox_3.clear()  
        for i in range (1,3):
            self.clearthings(1)
        self.quit_Qaction.triggered.connect(self.quit_app)
        self.actionAbout.triggered.connect(self.about)          
        self.selectDB_QAction.triggered.connect(self.selectFile)          
        self.selectDB_QPushButton.clicked.connect(self.selectFile)          
        # whenever Time Series Table is changed, the column-combobox must be updated and TableCheck must be performed (function partial due to problems with currentindexChanged and Combobox)
        #self.connect(self.table_ComboBox_1, QtCore.SIGNAL("currentIndexChanged(int)"), partial(self.Table1Changed))#currentIndexChanged caused unnecessary signals when scrolling in combobox
        self.connect(self.table_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Table1Changed))  
        self.connect(self.Filter1_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_1Changed))
        self.connect(self.Filter2_ComboBox_1, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_1Changed)) 
        self.connect(self.table_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Table2Changed)) 
        self.connect(self.Filter1_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_2Changed))
        self.connect(self.Filter2_ComboBox_2, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_2Changed)) 
        self.connect(self.table_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Table3Changed)) 
        self.connect(self.Filter1_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Filter1_3Changed))
        self.connect(self.Filter2_ComboBox_3, QtCore.SIGNAL("activated(int)"), partial(self.Filter2_3Changed)) 
        self.PlotChart_QPushButton.clicked.connect(self.drawPlot)
        self.Redraw_pushButton.clicked.connect( self.refreshPlot )
        
        # Create a plot window with one single subplot
        self.figure = plt.figure() 
        self.axes = self.figure.add_subplot( 111 )
        self.canvas = FigureCanvas( self.figure )
        self.mpltoolbar = NavigationToolbar( self.canvas, self.widgetPlot )
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction( lstActions[ 7 ] )
        self.layoutplot.addWidget( self.canvas )
        self.layoutplot.addWidget( self.mpltoolbar )

        # Search for saved settings and load as preset values
        self.settings = QtCore.QSettings('foo','foo')
        self.readsettings()

        self.show()
        
    def quit_app(self):
        self.close()
        #QtSql.QSqlDatabase.removeDatabase("db1")
        QtCore.QCoreApplication.instance().quit()

    def drawPlot(self):
        QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor))#show the user this may take a long time...

        self.storesettings()    #db, table, x-col and y-col are saved as default values when user clicks 'plot chart'
        self.axes.clear()
        My_format = [('date_time', datetime.datetime), ('values', float)] #Define (with help from function datetime) a good format for numpy array
        
        conn = sqlite.connect(np.unicode(self.selected_database_QLineEdit.text()),detect_types=sqlite.PARSE_DECLTYPES|sqlite.PARSE_COLNAMES)#should be cross-platform
        # skapa en cursor
        curs = conn.cursor()

        i = 0
        nop=0# nop=number of plots
        self.p=[]
        self.plabels=[]
        if not (self.table1 == '' or self.table1==' ') and not (self.xcol1== '' or self.xcol1==' ') and not (self.ycol1== '' or self.ycol1==' '): #if anything is to be plotted from tab 1
            self.maxtstep = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable1='y'
            filter1 = np.unicode(self.Filter1_ComboBox_1.currentText())
            filter1list = self.Filter1_QListWidget_1.selectedItems()
            filter2 = np.unicode(self.Filter2_ComboBox_1.currentText())
            filter2list= self.Filter2_QListWidget_1.selectedItems()
            nop += max(len(filter1list),1)*max(len(filter2list),1)
            #self.p= [None]*nop#list for plot objects
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            while i < len(self.p):
                if not (filter1 == '' or filter1==' ') and not (filter2== '' or filter2==' '):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + np.unicode(self.xcol_ComboBox_1.currentText()) + """, """ + np.unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + np.unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' and """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol_ComboBox_1.currentText())
                            self.plabels[i] = np.unicode(item1.text()) + """, """ + np.unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText())
                            i += 1
                elif not (filter1 == '' or filter1==' '):
                    for item1 in filter1list:
                        sql = r""" select """ + np.unicode(self.xcol_ComboBox_1.currentText()) + """, """ + np.unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + np.unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' order by """ + np.unicode(self.xcol_ComboBox_1.currentText())
                        self.plabels[i] = np.unicode(item1.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText())
                        i += 1
                elif not (filter2 == '' or filter2==' '):
                    for item2 in filter2list:
                        sql = r""" select """ + np.unicode(self.xcol_ComboBox_1.currentText()) + """, """ + np.unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + np.unicode(self.table_ComboBox_1.currentText()) + """ where """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol_ComboBox_1.currentText())
                        self.plabels[i] = np.unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText())
                        i += 1
                else:
                    sql = r""" select """ + np.unicode(self.xcol_ComboBox_1.currentText()) + """, """ + np.unicode(self.ycol_ComboBox_1.currentText()) + """ from """ + np.unicode(self.table_ComboBox_1.currentText()) + """ order by """ + np.unicode(self.xcol_ComboBox_1.currentText())
                    self.plabels[i] = np.unicode(self.ycol_ComboBox_1.currentText())+""", """+np.unicode(self.table_ComboBox_1.currentText())
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_1.currentText())
                    i += 1

        if not (self.table2 == '' or self.table2==' ') and not (self.xcol2== '' or self.xcol2==' ') and not (self.ycol2== '' or self.ycol2==' '):#if anything is to be plotted from tab 2
            self.maxtstep = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable2='y'
            filter1 = np.unicode(self.Filter1_ComboBox_2.currentText())
            filter1list = self.Filter1_QListWidget_2.selectedItems()
            filter2 = np.unicode(self.Filter2_ComboBox_2.currentText())
            filter2list= self.Filter2_QListWidget_2.selectedItems()
            nop =+ max(len(filter1list),1)*max(len(filter2list),1)
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            while i < len(self.p):
                if not (filter1 == '' or filter1==' ') and not (filter2== '' or filter2==' '):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + np.unicode(self.xcol2) + """, """ + np.unicode(self.ycol2) + """ from """ + np.unicode(self.table2) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' and """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol2)
                            self.plabels[i] = np.unicode(item1.text()) + """, """ + np.unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText())
                            i += 1
                elif not (filter1 == '' or filter1==' '):
                    for item1 in filter1list:
                        sql = r""" select """ + np.unicode(self.xcol2) + """, """ + np.unicode(self.ycol2) + """ from """ + np.unicode(self.table2) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' order by """ + np.unicode(self.xcol2)
                        self.plabels[i] = np.unicode(item1.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText())
                        i += 1
                elif not (filter2 == '' or filter2==' '):
                    for item2 in filter2list:
                        sql = r""" select """ + np.unicode(self.xcol2) + """, """ + np.unicode(self.ycol2) + """ from """ + np.unicode(self.table2) + """ where """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol2)
                        self.plabels[i] = np.unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText())
                        i += 1
                else:
                    sql = r""" select """ + np.unicode(self.xcol2) + """, """ + np.unicode(self.ycol2) + """ from """ + np.unicode(self.table2) + """ order by """ + np.unicode(self.xcol2)
                    self.plabels[i] = np.unicode(self.ycol2)+""", """+np.unicode(self.table2)
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_2.currentText())
                    i += 1

        if not (self.table3 == '' or self.table3==' ') and not (self.xcol3== '' or self.xcol3==' ') and not (self.ycol3== '' or self.ycol3==' '):#if anything is to be plotted from tab 3
            self.maxtstep = self.spnmaxtstep.value()   # if user selected a time step bigger than zero than thre may be discontinuous plots
            plottable3='y'
            filter1 = np.unicode(self.Filter1_ComboBox_3.currentText())
            filter1list = self.Filter1_QListWidget_3.selectedItems()
            filter2 = np.unicode(self.Filter2_ComboBox_3.currentText())
            filter2list= self.Filter2_QListWidget_3.selectedItems()
            nop =+ max(len(filter1list),1)*max(len(filter2list),1)
            self.p.extend([None]*nop)#list for plot objects
            self.plabels.extend([None]*nop)# List for plot labels
            while i < len(self.p):
                if not (filter1 == '' or filter1==' ') and not (filter2== '' or filter2==' '):
                    for item1 in filter1list:
                        for item2 in filter2list:
                            sql = r""" select """ + np.unicode(self.xcol3) + """, """ + np.unicode(self.ycol3) + """ from """ + np.unicode(self.table3) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' and """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol3)
                            self.plabels[i] = np.unicode(item1.text()) + """, """ + np.unicode(item2.text())
                            self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText())
                            i += 1
                elif not (filter1 == '' or filter1==' '):
                    for item1 in filter1list:
                        sql = r""" select """ + np.unicode(self.xcol3) + """, """ + np.unicode(self.ycol3) + """ from """ + np.unicode(self.table3) + """ where """ + filter1 + """='""" + np.unicode(item1.text())+ """' order by """ + np.unicode(self.xcol3)
                        self.plabels[i] = np.unicode(item1.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText())
                        i += 1
                elif not (filter2 == '' or filter2==' '):
                    for item2 in filter2list:
                        sql = r""" select """ + np.unicode(self.xcol3) + """, """ + np.unicode(self.ycol3) + """ from """ + np.unicode(self.table3) + """ where """ + filter2 + """='""" + np.unicode(item2.text())+ """' order by """ + np.unicode(self.xcol3)
                        self.plabels[i] = np.unicode(item2.text())
                        self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText())
                        i += 1
                else:
                    sql = r""" select """ + np.unicode(self.xcol3) + """, """ + np.unicode(self.ycol3) + """ from """ + np.unicode(self.table3) + """ order by """ + np.unicode(self.xcol3)
                    self.plabels[i] = np.unicode(self.ycol3)+""", """+np.unicode(self.table3)
                    self.createsingleplotobject(sql,i,My_format,curs,self.PlotType_comboBox_3.currentText())
                    i += 1

        #rs.close() # close the cursor
        conn.close()  # close the database
        self.refreshPlot()
        QtGui.QApplication.restoreOverrideCursor()#now this long process is done and the cursor is back as normal

    def createsingleplotobject(self,sql,i,My_format,curs,plottype='line'):
        rs = curs.execute(sql) #Send SQL-syntax to cursor
        recs = rs.fetchall()  # All data are stored in recs
        # late fix for xy-plots
        My_format2 = [('numx', float), ('values', float)]#define a format for xy-plot (to use if not datetime on x-axis)
        #Transform data to a numpy.recarray
        try:
            table = np.array(recs, dtype=My_format)  #NDARRAY
            table2=table.view(np.recarray)   # RECARRAY transform the 2 cols into callable objects
            myTimestring = []  #LIST
            FlagTimeXY = 'time'
            j = 0
            for row in table2:
                myTimestring.append(table2.date_time[j])
                j = j + 1
            numtime=datestr2num(myTimestring)  #conv list of strings to numpy.ndarray of floats
        except:
            table = np.array(recs, dtype=My_format2)  #NDARRAY
            table2=table.view(np.recarray)   # RECARRAY transform the 2 cols into callable objects
            myXYstring = []  #LIST
            FlagTimeXY = 'XY'
            j = 0
            for row in table2: #
                myXYstring.append(table2.numx[j])
                j = j + 1
            numtime = myXYstring

        # from version 0.2 there is a possibility to make discontinuous plot if timestep bigger than maxtstep
        if self.maxtstep > 0: # if user selected a time step bigger than zero than thre may be discontinuous plots
            pos = np.where(np.abs(np.diff(numtime)) >= self.maxtstep)[0]
            numtime[pos] = np.nan
            table2.values[pos] = np.nan

        if plottype == "marker":
            MarkVar = 'o'
        elif plottype  == "line":
            MarkVar = '-'
        elif plottype  == "line and cross":
            MarkVar = '+-'
        else:
            MarkVar = 'o-'

        if FlagTimeXY == "time" and plottype == "step-pre":
            self.p[i], = self.axes.plot_date(numtime, table2.values, drawstyle='steps-pre', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i])# 'steps-pre' best for precipitation and flowmeters, optional types are 'steps', 'steps-mid', 'steps-post'
        elif FlagTimeXY == "time" and plottype == "step-post":
            self.p[i], = self.axes.plot_date(numtime, table2.values, drawstyle='steps-post', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i])
        elif FlagTimeXY == "time" and plottype == "line and cross":
            self.p[i], = self.axes.plot_date(numtime, table2.values,  MarkVar,markersize = 6, label=self.plabels[i])
        elif FlagTimeXY == "time":
            self.p[i], = self.axes.plot_date(numtime, table2.values,  MarkVar,label=self.plabels[i])
        elif FlagTimeXY == "XY" and plottype == "step-pre":
            self.p[i], = self.axes.plot(numtime, table2.values, drawstyle='steps-pre', linestyle='-', marker='None',c=np.random.rand(3,1),label=self.plabels[i]) 
        elif FlagTimeXY == "XY" and plottype == "step-post":
            self.p[i], = self.axes.plot(numtime, table2.values, drawstyle='steps-post', linestyle='-', marker='None',c=np.random.rand(3,1),abel=self.plabels[i]) 
        elif FlagTimeXY == "XY" and plottype == "line and cross":
            self.p[i], = self.axes.plot(numtime, table2.values,  MarkVar,markersize = 6, label=self.plabels[i])
        else:
            self.p[i], = self.axes.plot(numtime, table2.values,  MarkVar,label=self.plabels[i])

    def refreshPlot( self ):
        self.axes.legend_=None
        #self.axes.clear()
        #self.plabels = ('Rb1103','Rb1104')#debugging
        #print self.plabels #debug
        datemin = self.spnMinX.dateTime().toPyDateTime()
        datemax = self.spnMaxX.dateTime().toPyDateTime()
        if datemin == datemax: #xaxis-limits
            pass
        else:
            self.axes.set_xlim(min(datemin, datemax),max(datemin, datemax))
        if self.spnMinY.value() == self.spnMaxY.value(): #yaxis-limits
            pass
        else:
            self.axes.set_ylim(min(self.spnMaxY.value(), self.spnMinY.value()),max(self.spnMaxY.value(), self.spnMinY.value()))
        self.axes.yaxis.set_major_formatter(tick.ScalarFormatter(useOffset=False, useMathText=False))#yaxis-format
        self.figure.autofmt_xdate()#xaxis-format
        self.axes.grid(self.Grid_checkBox.isChecked() )#grid
        if not self.title_QLineEdit.text()=='':#title
            self.axes.set_title(self.title_QLineEdit.text())
        if not self.xtitle_QLineEdit.text()=='':#xaxis label
            self.axes.set_xlabel(self.xtitle_QLineEdit.text())
        if not self.ytitle_QLineEdit.text()=='':#yaxis label
            self.axes.set_ylabel(self.ytitle_QLineEdit.text())
        for label in self.axes.xaxis.get_ticklabels():
            label.set_fontsize(10)
        for label in self.axes.yaxis.get_ticklabels():
            label.set_fontsize(10)
        # finally, the legend
        if self.Legend_checkBox.isChecked():
            if (self.spnLegX.value() ==0 ) and (self.spnLegY.value() ==0):
                leg = self.axes.legend(self.p, self.plabels)
            else:
                leg = self.axes.legend(self.p, self.plabels, bbox_to_anchor=(self.spnLegX.value(),self.spnLegY.value()),loc=10)
            leg.draggable(state=True)
            frame  = leg.get_frame()    # the matplotlib.patches.Rectangle instance surrounding the legend
            frame.set_facecolor('1')    # set the frame face color to white
            frame.set_fill(False)    # set the frame face color to white
            for t in leg.get_texts():
                t.set_fontsize(10)    # the legend text fontsize
        else:
            self.axes.legend_=None

        self.figure.autofmt_xdate()
        self.canvas.draw()

    def selectFile(self):   #Open a dialog to locate the sqlite file and some more...
        try:
            from PyQt4.QtCore import QString
            message=QtCore.QString.fromLocal8Bit("Select database:")
        except ImportError:
            message = str("Select database:")
        path = QtGui.QFileDialog.getOpenFileName(None,message,"*.sqlite")
        if path:
            self.database = path # To make possible cancel the FileDialog and continue loading a predefined db
        self.openDBFile()

    def openDBFile( self ):    # Open the SpatiaLite file to extract info about tables
        if os.path.isfile( np.unicode( self.database ) ):
            self.selected_database_QLineEdit.setText(self.database)
            self.table_ComboBox_1.clear()
            self.table_ComboBox_2.clear()
            self.table_ComboBox_3.clear()
            for i in range (1,3):
                self.clearthings(1)

            conn = sqlite.connect( np.unicode(self.database) )
            cursor = conn.cursor()
            rs=cursor.execute(r"""SELECT tbl_name FROM sqlite_master WHERE (type='table' or type='view') and not (name in('geom_cols_ref_sys',
                'geometry_columns',
                'geometry_columns_time',
                'spatial_ref_sys',
                'spatialite_history',
                'vector_layers',
                'views_geometry_columns',
                'virts_geometry_columns',
                'geometry_columns_auth',
                'geometry_columns_fields_infos',
                'geometry_columns_statistics',
                'sql_statements_log',
                'layer_statistics',
                'sqlite_sequence',
                'sqlite_stat1' ,
                'views_layer_statistics',
                'virts_layer_statistics',
                'vector_layers_auth',
                'vector_layers_field_infos',
                'vector_layers_statistics',
                'views_geometry_columns_auth',
                'views_geometry_columns_field_infos',
                'views_geometry_columns_statistics',
                'virts_geometry_columns_auth',
                'virts_geometry_columns_field_infos',
                'virts_geometry_columns_statistics' ,
                'geometry_columns',
                'spatialindex',
                'SpatialIndex')) ORDER BY tbl_name"""  )  #SQL statement to get the relevant tables in the spatialite database
            #self.dbTables = {}
            self.table_ComboBox_1.addItem('')
            self.table_ComboBox_2.addItem('')
            self.table_ComboBox_3.addItem('')

            for row in cursor:
                self.table_ComboBox_1.addItem(row[0])
                self.table_ComboBox_2.addItem(row[0])
                self.table_ComboBox_3.addItem(row[0])

            rs.close()
            conn.close()

    def clearthings(self,tabno=1):   #clear xcol,ycol,fukter1,filter2
        xcolcombobox = 'xcol_ComboBox_' + str(tabno)
        ycolcombobox = 'ycol_ComboBox_' + str(tabno)
        filter1combobox = 'Filter1_ComboBox_' + str(tabno)
        filter2combobox = 'Filter2_ComboBox_' + str(tabno)
        filter1qlistwidget = 'Filter1_QListWidget_' + str(tabno)
        filter2qlistwidget = 'Filter2_QListWidget_' + str(tabno)
        getattr(self,xcolcombobox).clear()
        getattr(self,ycolcombobox).clear()
        getattr(self,filter1combobox).clear()
        getattr(self,filter2combobox).clear()
        getattr(self,filter1qlistwidget).clear()
        getattr(self,filter2qlistwidget).clear()

    def Table1Changed(self):     #This method is called whenever table1 is changed
        # First, update combobox with columns
        self.clearthings(1)
        self.table1 = np.unicode(self.table_ComboBox_1.currentText())
        self.PopulateComboBox('xcol_ComboBox_1', self.table_ComboBox_1.currentText())  # GeneralNote: For some reason it is not possible to send currentText with the SIGNAL-trigger
        self.PopulateComboBox('ycol_ComboBox_1', self.table_ComboBox_1.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter1_ComboBox_1', self.table_ComboBox_1.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter2_ComboBox_1', self.table_ComboBox_1.currentText())  # See GeneralNote

    def Table2Changed(self):     #This method is called whenever table2 is changed
        # First, update combobox with columns
        self.clearthings(2)
        self.table2 = np.unicode(self.table_ComboBox_2.currentText())
        self.PopulateComboBox('xcol_ComboBox_2', self.table_ComboBox_2.currentText())  # GeneralNote: For some reason it is not possible to send currentText with the SIGNAL-trigger
        self.PopulateComboBox('ycol_ComboBox_2', self.table_ComboBox_2.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter1_ComboBox_2', self.table_ComboBox_2.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter2_ComboBox_2', self.table_ComboBox_2.currentText())  # See GeneralNote

    def Table3Changed(self):     #This method is called whenever table3 is changed
        # First, update combobox with columns
        self.clearthings(3)
        self.table3 = np.unicode(self.table_ComboBox_3.currentText())
        self.PopulateComboBox('xcol_ComboBox_3', self.table_ComboBox_3.currentText())  # GeneralNote: For some reason it is not possible to send currentText with the SIGNAL-trigger
        self.PopulateComboBox('ycol_ComboBox_3', self.table_ComboBox_3.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter1_ComboBox_3', self.table_ComboBox_3.currentText())  # See GeneralNote
        self.PopulateComboBox('Filter2_ComboBox_3', self.table_ComboBox_3.currentText())  # See GeneralNote

    def PopulateComboBox(self, comboboxname='', table=None):
        """This method fills comboboxes with columns for selected tool and table"""
        columns = self.LoadColumnsFromTable(table)    # Load all columns into a list 'columns'
        if len(columns)>0:    # Transfer information from list 'columns' to the combobox
            getattr(self, comboboxname).addItem('')
            for columnName in columns:
                getattr(self, comboboxname).addItem(columnName)  # getattr is to combine a function and a string to a combined function

    def LoadColumnsFromTable(self, table=''):
        """ This method returns a list with all the columns in the table"""
        if len(table)>0 and len(self.database)>0:            # Should not be needed since the function never should be called without existing table...
            conn = sqlite.connect(np.unicode(self.database))
            curs = conn.cursor()
            sql = r"""SELECT * FROM '"""
            sql += np.unicode(table)
            sql += """'"""
            rs = curs.execute(sql)  #Send the SQL statement to get the columns in the table
            columns = {}
            columns = [tuple[0] for tuple in curs.description]
            rs.close()
            conn.close()
        else:
            #QMessageBox.information(None,"info","no table is loaded")    # DEBUGGING
            columns = {}
        return columns        # This method returns a list with all the columns in the table

    def Filter1_1Changed(self):
        self.Filter1_QListWidget_1.clear()
        if not self.Filter1_ComboBox_1.currentText()=='':
            self.PopulateFilterList(self.table1,'Filter1_QListWidget_1', self.Filter1_ComboBox_1.currentText())  # For some reason it is not possible to send currentText with the SIGNAL-trigger

    def Filter2_1Changed(self):
        self.Filter2_QListWidget_1.clear()
        if not self.Filter2_ComboBox_1.currentText()=='':
            self.PopulateFilterList(self.table1,'Filter2_QListWidget_1', self.Filter2_ComboBox_1.currentText())  # For some reason it is not possible to send currentText with the SIGNAL-trigger

    def Filter1_2Changed(self):
        self.Filter1_QListWidget_2.clear()
        if not self.Filter1_ComboBox_2.currentText()=='':
            self.PopulateFilterList(self.table2,'Filter1_QListWidget_2', self.Filter1_ComboBox_2.currentText())

    def Filter2_2Changed(self):
        self.Filter2_QListWidget_2.clear()
        if not self.Filter2_ComboBox_2.currentText()=='':
            self.PopulateFilterList(self.table2,'Filter2_QListWidget_2', self.Filter2_ComboBox_2.currentText())

    def Filter1_3Changed(self):
        self.Filter1_QListWidget_3.clear()
        if not self.Filter1_ComboBox_3.currentText()=='':
            self.PopulateFilterList(self.table3,'Filter1_QListWidget_3', self.Filter1_ComboBox_3.currentText())

    def Filter2_3Changed(self):
        self.Filter2_QListWidget_3.clear()
        if not self.Filter2_ComboBox_3.currentText()=='':
            self.PopulateFilterList(self.table3,'Filter2_QListWidget_3', self.Filter2_ComboBox_3.currentText())

    def PopulateFilterList(self, table, QListWidgetname='', filtercolumn=None):
        sql = "select distinct " + np.unicode(filtercolumn) + " from " + table + " order by " + np.unicode(filtercolumn)
        list_data=sql_load_fr_db(self.database, sql)
        for post in list_data:
            item = QtGui.QListWidgetItem(np.unicode(post[0]))
            getattr(self, QListWidgetname).addItem(item)

    def storesettings(self):
        self.settings.setValue('db',self.database)
        self.settings.setValue('table1', self.table_ComboBox_1.currentText())
        self.settings.setValue('xcol1', self.xcol_ComboBox_1.currentText())
        self.settings.setValue('ycol1', self.ycol_ComboBox_1.currentText())
        self.table1=self.table_ComboBox_1.currentText()
        self.xcol1=self.xcol_ComboBox_1.currentText()
        self.ycol1=self.ycol_ComboBox_1.currentText()
        self.settings.setValue('table2', self.table_ComboBox_2.currentText())
        self.settings.setValue('xcol2', self.xcol_ComboBox_2.currentText())
        self.settings.setValue('ycol2', self.ycol_ComboBox_2.currentText())
        self.table2=self.table_ComboBox_2.currentText()
        self.xcol2=self.xcol_ComboBox_2.currentText()
        self.ycol2=self.ycol_ComboBox_2.currentText()
        self.settings.setValue('table3', self.table_ComboBox_3.currentText())
        self.settings.setValue('xcol3', self.xcol_ComboBox_3.currentText())
        self.settings.setValue('ycol3', self.ycol_ComboBox_3.currentText())
        self.table3=self.table_ComboBox_3.currentText()
        self.xcol3=self.xcol_ComboBox_3.currentText()
        self.ycol3=self.ycol_ComboBox_3.currentText()

    def readsettings(self): #only used when application starts, to load default values from last run
        try:
            l1 = len((self.settings.value('db')).toString())
        except:
            l1 = len(str(self.settings.value('db')))
        if l1>0:
            self.database = self.settings.value('db',type='QString')
            #print self.database
            self.openDBFile()

            try:#table1
                self.table1 = self.settings.value('table1').toString()
                notfound=0
                i=0
                while notfound==0:    # Loop until the last selected table1 is found
                    self.table_ComboBox_1.setCurrentIndex(i)
                    if self.table_ComboBox_1.currentText() == self.table1: #The index count stops when last selected table is found
                        notfound=1
                        self.Table1Changed() # Fill xcol,ycol,filter1,filter2 comboboxes with info from selected table
                        try:#xcol1
                            self.xcol1 = self.settings.value('xcol1').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.xcol_ComboBox_1.setCurrentIndex(j)
                                if self.xcol_ComboBox_1.currentText() == self.xcol1: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.xcol_ComboBox_1):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for xcolumn')
                        try:#ycol1
                            self.ycol1 = self.settings.value('ycol1').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.ycol_ComboBox_1.setCurrentIndex(j)
                                if self.ycol_ComboBox_1.currentText() == self.ycol1: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.ycol_ComboBox_1):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for ycolumn')
                    elif i> len(self.table_ComboBox_1):
                        notfound=1
                    i = i + 1
            except:
                print('nothing to be done for table1')

            try:#table2
                self.table2 = self.settings.value('table2').toString()
                notfound=0
                i=0
                while notfound==0:    # Loop until the last selected table2 is found
                    self.table_ComboBox_2.setCurrentIndex(i)
                    if self.table_ComboBox_2.currentText() == self.table2: #The index count stops when last selected table is found
                        notfound=1
                        self.Table2Changed() # Fill xcol,ycol,filter1,filter2 comboboxes with info from selected table
                        try:#xcol2
                            self.xcol2 = self.settings.value('xcol2').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.xcol_ComboBox_2.setCurrentIndex(j)
                                if self.xcol_ComboBox_2.currentText() == self.xcol2: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.xcol_ComboBox_2):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for xcolumn')
                        try:#ycol2
                            self.ycol2 = self.settings.value('ycol2').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.ycol_ComboBox_2.setCurrentIndex(j)
                                if self.ycol_ComboBox_2.currentText() == self.ycol2: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.ycol_ComboBox_2):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for ycolumn')
                    elif i> len(self.table_ComboBox_2):
                        notfound=1
                    i = i + 1
            except:
                print('nothing to be done for table2')

            try:#table3
                self.table3 = self.settings.value('table3').toString()
                notfound=0
                i=0
                while notfound==0:    # Loop until the last selected table2 is found
                    self.table_ComboBox_3.setCurrentIndex(i)
                    if self.table_ComboBox_3.currentText() == self.table3: #The index count stops when last selected table is found
                        notfound=1
                        self.Table3Changed() # Fill xcol,ycol,filter1,filter2 comboboxes with info from selected table
                        try:#xcol3
                            self.xcol3 = self.settings.value('xcol3').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.xcol_ComboBox_3.setCurrentIndex(j)
                                if self.xcol_ComboBox_3.currentText() == self.xcol3: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.xcol_ComboBox_3):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for xcolumn')
                        try:#ycol3
                            self.ycol3 = self.settings.value('ycol3').toString()
                            notfound2=0
                            j=0
                            while notfound2==0:    # loop until the last selected tscolumn is found
                                self.ycol_ComboBox_3.setCurrentIndex(j)
                                if self.ycol_ComboBox_3.currentText() == self.ycol3: # index count stops when column found
                                    notfound2=1
                                elif j> len(self.ycol_ComboBox_3):
                                    notfound2=1
                                j = j + 1
                        except:
                            print('no stored data for ycolumn')
                    elif i> len(self.table_ComboBox_3):
                        notfound=1
                    i = i + 1
            except:
                print('nothing to be done for table3')

    def about(self):
        version = u'0.2.4'
        contact = u'*****@*****.**'
        web = u'http://sourceforge.net/projects/plotsqlite'
        TEXT = 'This is PlotSQLite - the Midvatten plot generator.\n\nVersion: ' + version + '\nContact: ' + contact + '\nMore info: ' + web
        QtGui.QMessageBox.information(None, "info", TEXT)
Esempio n. 10
0
class MatplotlibWidget(QtGui.QWidget):
    '''Base class for matplotlib widgets
    '''
    def __init__(self, parent):
        '''Inits matplotlib widget.
        
        Args:
            parent: A Parent class object.
        '''
        super().__init__()
        self.main_frame = parent
        self.dpi = 75
        self.show_axis_ticks = True
        self.__create_frame()


    def __create_frame(self):
        self.fig = Figure((5.0, 3.0), dpi=self.dpi)
        self.fig.patch.set_facecolor("white")
        self.canvas = FigureCanvas(self.fig)
        self.canvas.manager = MockManager(self.main_frame)
        self.canvas.setParent(self.main_frame)
        self.axes = self.fig.add_subplot(111)
        
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
        hbox = QtGui.QHBoxLayout()
        
        self.main_frame.ui.matplotlib_layout.addWidget(self.canvas)
        self.main_frame.ui.matplotlib_layout.addWidget(self.mpl_toolbar)
        self.main_frame.ui.matplotlib_layout.addLayout(hbox)


    def fork_toolbar_buttons(self):
        '''Remove figure options & subplot config that might not work properly.
        '''
        try:
            self.mpl_toolbar.removeAction(self.mpl_toolbar.children()[21]) 
            self.mpl_toolbar.removeAction(self.mpl_toolbar.children()[17])
        except:
            pass  # Already removed
    
    
    def remove_axes_ticks(self):
        '''Remove ticks from axes.
        '''
        if not self.show_axis_ticks:
            for tick in self.axes.yaxis.get_major_ticks():
                tick.label1On = False
                tick.label2On = False
            for tick in self.axes.xaxis.get_major_ticks():
                tick.label1On = False
                tick.label2On = False
                
                
    def delete(self):
        '''Delete matplotlib objects.
        '''
        self.axes.clear()  # Might be useless with fig.clf()
        self.canvas.close()
        self.fig.clf()
        self.close()
        
        del self.fig
        del self.canvas
        del self.axes
        
        import gc
        gc.collect()