class Ui_plotWindow(QtGui.QWidget, subpanel):
    def setupUi(self, plotWindow, commTransport):
        plotWindow.setObjectName(_fromUtf8("plotWindow"))
        plotWindow.resize(818, 418)
        self.gridLayout = QtGui.QGridLayout(plotWindow)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.graphicsView = PlotWidget(plotWindow)
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
        self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1)

        self.retranslateUi(plotWindow)
        QtCore.QMetaObject.connectSlotsByName(plotWindow)
        
        self.serialComm = commTransport
        self.graphicsView.hideAxis('bottom')
        self.graphicsView.getAxis('left').setWidth(100)
        
        # custom code added
        '''
        self.dataPlot.hideAxis('bottom')
        self.dataPlot.showGrid(y=True)
        self.dataPlot.getAxis('left').setWidth(100)
        
        plotSize = 256
        self.plotCount = 6

        self.output = []
        for i in range(self.plotCount):
            self.output.append(deque([0.0]*plotSize))
            
        self.axis = deque(range(plotSize))
        self.value = plotSize
        '''

    def retranslateUi(self, plotWindow):
        plotWindow.setWindowTitle(QtGui.QApplication.translate("plotWindow", "Form", None, QtGui.QApplication.UnicodeUTF8))

    def readContinuousData(self, serialComm):
        '''
Exemple #2
0
class widget_mfi_plot(QWidget):

    #-----------------------------------------------------------------------
    # DEFINE THE INITIALIZATION FUNCTION.
    #-----------------------------------------------------------------------

    def __init__(self, core):

        # Inherit all attributes of an instance of "QWidget".

        super(widget_mfi_plot, self).__init__()

        # Store the Janus core.

        self.core = core

        # Prepare to respond to signals received from the core.

        self.connect(self.core, SIGNAL('janus_rset'), self.resp_rset)
        self.connect(self.core, SIGNAL('janus_chng_mfi'), self.resp_chng_mfi)

        # Initialize this widget's instance of "PlotWidget", which will
        # contain the plot of MFI magnetic field data.

        # Note.  The "QGridLayout" object given to this widget as its
        #        layout is essentially a dummy.  I could have just had
        #        this class inherit "PlotWidget", but I think that this
        #        gives me a bit more control (and a similar structure
        #        "janus_widget_fc_cup").

        self.setLayout(QGridLayout())

        self.plt = PlotWidget()
        self.layout().addWidget(self.plt)

        self.layout().setContentsMargins(0, 0, 0, 0)

        # Extract the individual elements of the "PlotWidget" object
        # (e.g., it's axes) for more convenient access later.

        self.vbx = self.plt.getViewBox()

        self.axs_x = self.plt.getAxis('bottom')
        self.axs_y = self.plt.getAxis('left')

        self.ptm = self.plt.getPlotItem()

        # Initialize and store the pens and fonts.

        self.pen_vbx = mkPen(color='k')
        self.pen_crv_m = mkPen(color='k')
        self.pen_crv_n = mkPen(color='k')
        self.pen_crv_x = mkPen(color='r')
        self.pen_crv_y = mkPen(color='g')
        self.pen_crv_z = mkPen(color='b')

        self.fnt = self.core.app.font()

        # Configure the plot: disable automatic adjustments and
        # adjustments made by the user, change the background and
        # foreground colors, enable grid lines for both axes, label the
        # axes, adjust the tick font size, adjust the "AxisItem" sizes,
        # and add a margin around the entire plot.

        self.plt.disableAutoRange()
        self.plt.setMouseEnabled(False, False)
        self.plt.setMenuEnabled(False)
        self.plt.hideButtons()

        self.plt.setBackground('w')
        setConfigOption('foreground', 'k')

        #####self.plt.showGrid( True, True )

        labelStyle = {'color': 'k'}
        self.axs_x.setLabel('Time [s]', **labelStyle)
        self.axs_y.setLabel('Magnetic Field [nT]', **labelStyle)

        self.axs_x.label.setFont(self.fnt)
        self.axs_y.label.setFont(self.fnt)

        self.axs_x.setTickFont(self.fnt)
        self.axs_y.setTickFont(self.fnt)

        self.axs_x.setHeight(35)
        self.axs_y.setWidth(40)

        self.vbx.border = self.pen_vbx

        self.ptm.setContentsMargins(5, 5, 5, 5)

        # Initialize the curves that will be added to this plot.

        self.crv_m = None
        self.crv_n = None
        self.crv_x = None
        self.crv_y = None
        self.crv_z = None

        # Populate this plot and adjust it's settings.

        self.make_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR POPULATING THE PLOT.
    #-----------------------------------------------------------------------

    def make_plt(self):

        # Reset the plot (i.e., remove all plot elements).

        self.rset_plt()

        # Establish the ranges of its time and magnetic field values.
        # If the core contains no data or only a single datum,
        # improvise (for the purpose of later establishing axis limits).

        if (self.core.n_mfi >= 1):

            # Establish the domain of the plot.

            t_min = min(amin(self.core.mfi_t), 0.)
            t_max = max(amax(self.core.mfi_t), self.core.dur_sec)

            # Establish the range of the plot.  As part of this,
            # ensure that the range satisfies a minimum size and has
            # sufficient padding.

            b_max = amax(self.core.mfi_b)
            b_min = -b_max

            d_t_0 = t_max - t_min
            d_b_0 = b_max - b_min

            d_t = max(1.5 + d_t_0, 3.)
            d_b = max(1.2 * d_b_0, 5.)

            t_max = t_min + d_t

            b_min = b_min - (d_b - d_b_0) / 2.
            b_max = b_max + (d_b - d_b_0) / 2.

        else:

            t_min = 0.001
            t_max = 3.500

            b_min = -2.5
            b_max = 2.5

        # Set the range of the axis of each plot.

        self.plt.setXRange(t_min, t_max, padding=0.0)
        self.plt.setYRange(b_min, b_max, padding=0.0)

        # If the core contains no Wind/MFI magnetic field data, return.

        if (self.core.n_mfi <= 0):
            return

        # Generate and display each curve for the plot.

        self.crv_m = PlotDataItem(self.core.mfi_t,
                                  self.core.mfi_b,
                                  pen=self.pen_crv_m)
        self.crv_n = PlotDataItem(self.core.mfi_t,
                                  -self.core.mfi_b,
                                  pen=self.pen_crv_n)
        self.crv_x = PlotDataItem(self.core.mfi_t,
                                  self.core.mfi_b_x,
                                  pen=self.pen_crv_x)
        self.crv_y = PlotDataItem(self.core.mfi_t,
                                  self.core.mfi_b_y,
                                  pen=self.pen_crv_y)
        self.crv_z = PlotDataItem(self.core.mfi_t,
                                  self.core.mfi_b_z,
                                  pen=self.pen_crv_z)

        self.plt.addItem(self.crv_m)
        self.plt.addItem(self.crv_n)
        self.plt.addItem(self.crv_x)
        self.plt.addItem(self.crv_y)
        self.plt.addItem(self.crv_z)

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESETTING THIS PLOT (CLEARING ALL ELEMENTS).
    #-----------------------------------------------------------------------

    def rset_plt(self):

        # Hide and remove each of this plot's elements.

        if (self.crv_m is not None):
            self.plt.removeItem(self.crv_m)

        if (self.crv_n is not None):
            self.plt.removeItem(self.crv_n)

        if (self.crv_x is not None):
            self.plt.removeItem(self.crv_x)

        if (self.crv_y is not None):
            self.plt.removeItem(self.crv_y)

        if (self.crv_z is not None):
            self.plt.removeItem(self.crv_z)

        # Permanently delete this plot's elements by setting each of the
        # variables that store them to "None".

        self.crv_m = None
        self.crv_n = None
        self.crv_x = None
        self.crv_y = None
        self.crv_z = None

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_rset(self):

        # Reset the plot.

        self.rset_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mfi" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_chng_mfi(self):

        # Regenerate the plot.

        self.make_plt()
Exemple #3
0
class FindPeak(QWidget):
    def __init__(self, parent, x_data, y_data):
        super(FindPeak, self).__init__()
        self.parent = parent
        self.x = x_data
        self.y = y_data
        self.lower = np.min(x_data)
        self.upper = np.max(x_data)
        self.range = self.upper - self.lower
        self.renderWindow()
        self.initPlotView()
        self.drawCurve()
        self.setUpProcessUI()
        self.bindEvents()
        self.integral(x_data, y_data, self.lower, self.upper)

    def bindEvents(self):
        self.bindBoundEvent()
        self.bindAlgorithmEvent()
        self.bindFindEvent()

    def bindBoundEvent(self):
        def leftBoundEvent(x):
            self.lower = x
            upper = self.upper
            self.plotRegion.setRegion([x, upper])
            self.rightBound.setMinimum(x)
            self.peakCenter.setMinimum(x)
            self.peakCenter.setValue((x + upper) / 2)
            self.integral(self.x, self.y, x, upper)

        def rightBoundEvent(x):
            self.upper = x
            lower = self.lower
            self.plotRegion.setRegion([lower, x])
            self.leftBound.setMaximum(x)
            self.peakCenter.setMaximum(x)
            self.peakCenter.setValue((x + lower) / 2)
            self.integral(self.x, self.y, lower, x)

        def regionChangeEvent():
            lower, upper = self.plotRegion.getRegion()
            self.lower = lower
            self.upper = upper
            self.leftBound.setValue(lower)
            self.leftBound.setMaximum(upper)
            self.rightBound.setValue(upper)
            self.rightBound.setMinimum(lower)
            self.peakCenter.setMinimum(lower)
            self.peakCenter.setMaximum(upper)
            self.peakCenter.setValue((lower + upper) / 2)
            self.integral(self.x, self.y, lower, upper)

        self.leftBound.valueChanged.connect(leftBoundEvent)
        self.rightBound.valueChanged.connect(rightBoundEvent)
        self.plotRegion.sigRegionChanged.connect(regionChangeEvent)

    def bindAlgorithmEvent(self):
        def updateInput(a, b, c, d, e, f):
            self.peakWidth.setEnabled(a)
            self.detectDis.setEnabled(b)
            self.noisePrt.setEnabled(c)
            self.amplitude.setEnabled(d)
            self.threshold.setEnabled(e)
            self.findBtn.setEnabled(f)

        def changeAlgorithm(algorithm):
            if algorithm == "Extremum":
                updateInput(False, False, False, False, False, True)
                pass
            elif algorithm == "Matlab Like":
                updateInput(True, True, False, True, True, True)
                pass
            elif algorithm == "Gaussian":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Lorentzian":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Pseudo-Voigt":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Wavelet Transform":
                updateInput(True, True, True, False, False, False)
                pass

        self.algorithm.currentTextChanged.connect(changeAlgorithm)
        updateInput(False, False, False, False, False, True)

    def integral(self, x_data, y_data, lower, upper):
        idx = np.where((x_data >= lower) & (x_data <= upper))
        x = x_data[idx]
        y = y_data[idx]
        self.integralArea.setValue(simps(y, x))

    def bindFindEvent(self):
        x_data = self.x
        y_data = self.y

        def findPeak():
            region = np.where((x_data >= self.lower) & (x_data <= self.upper))
            sub_data = y_data[region]
            sub_region = x_data[region]
            algorithm = self.algorithm.currentText()
            shape = self.shape.currentText()
            if shape == "Peak":
                const = 1
            else:
                const = -1
            sub_data = sub_data * const
            if algorithm == "Extremum":
                peak = np.max(sub_data)
                idx = np.where(sub_data == peak)
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
            elif algorithm == "Matlab Like":
                indexes = find_peaks(
                    sub_data,
                    height=self.amplitude.value(),  #低于指定高度忽略
                    threshold=self.threshold.value(),  #相邻两点高度差
                    distance=self.detectDis.value(),  #两峰间距
                    width=self.peakWidth.value()  #峰宽
                )[0]
                if np.size(indexes) == 0:
                    return
                idx = np.where(sub_data == np.max(sub_data[indexes]))
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
            elif algorithm == "Wavelet Transform":
                indexes = find_peaks_cwt(
                    sub_data,
                    widths=self.peakWidth.value(),  #峰宽
                    max_distances=self.detectDis.value(),  #两峰间距
                    noise_perc=self.noisePrt.value())[0]
                if np.size(indexes) == 0:
                    return
                idx = np.where(sub_data == np.max(sub_data[indexes]))
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
                self.noisePrt
            pass

        self.findBtn.clicked.connect(findPeak)

    def renderPeakPoint(self, pos):
        self.peakPoint.clear()
        self.peakPoint.addPoints([{'pos': pos, 'data': 1}])

    def renderWindow(self):
        #边框结构
        self.setGeometry(80, 80, 800, 420)
        size = self.geometry()
        screen = QDesktopWidget().screenGeometry()
        posX = (screen.width() - size.width()) / 2
        posY = (screen.height() - size.height()) / 2
        self.move(posX, posY)
        #标题
        self.setWindowTitle('Find Peak')
        self.setWindowIcon(QIcon('resource/curve.ico'))
        #布局
        layout = QGridLayout()
        self.graphicsView = QGridLayout()
        layout.addLayout(self.graphicsView, 0, 0, 1, 1)

        self.Process_Box = QGroupBox()
        self.Process_Box.setMinimumSize(200, 420)
        self.Process_Box.setFlat(True)
        layout.addWidget(self.Process_Box, 0, 1, 1, 1)

        self.setLayout(layout)

    def setUpProcessUI(self):
        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        self.Process_Box.setLayout(layout)

        layout.addWidget(QLabel(self.translate('Left Boundary')), 0, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Right Boundary')), 1, 0, 1, 1)
        layout.addWidget(QLabel(self.translate("Integral Area")), 2, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Peak Center')), 3, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Peak Shape')), 4, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Find Peak Algorithm')), 5, 0,
                         1, 1)
        layout.addWidget(QLabel(self.translate('Minimum Peak Width')), 6, 0, 1,
                         1)
        layout.addWidget(QLabel(self.translate('Minimum Detect Distance')), 7,
                         0, 1, 1)
        layout.addWidget(QLabel(self.translate('Noise Percent')), 8, 0, 1, 1)
        layout.addWidget(QLabel(self.translate("Minimum Amplitude")), 9, 0, 1,
                         1)
        layout.addWidget(QLabel(self.translate("Relative Threshold")), 10, 0,
                         1, 1)

        self.leftBound = SpinBox(lower=self.lower, dec=4, val=self.lower)
        self.rightBound = SpinBox(upper=self.upper, dec=4, val=self.upper)
        self.peakCenter = SpinBox(lower=self.lower, upper=self.upper, dec=4)
        self.peakWidth = SpinBox(lower=1, upper=10000, val=5)
        self.noisePrt = SpinBox(lower=0, upper=100, step=1, val=10)
        self.detectDis = SpinBox(lower=1, val=3)
        self.amplitude = SpinBox(lower=-1E5, upper=1E5, dec=4, val=-1)
        self.threshold = SpinBox(lower=0, upper=100, dec=4, val=0.001)
        self.integralArea = SpinBox(upper=1E8, dec=4)
        self.integralArea.setReadOnly(True)
        self.integralArea.setButtonSymbols(QAbstractSpinBox.NoButtons)

        self.shape = QComboBox()
        self.shape.addItems(["Peak", "Valley"])
        #self.shape.currentTextChanged.connect()

        self.algorithm = QComboBox()
        self.algorithm.addItems([
            'Extremum', 'Matlab Like', 'Wavelet Transform', 'Gaussian',
            'Lorentzian', 'Pseudo-Voigt'
        ])
        #self.algorithm.currentTextChanged.connect()
        #https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks_cwt.html
        layout.addWidget(self.leftBound, 0, 1, 1, 1)
        layout.addWidget(self.rightBound, 1, 1, 1, 1)
        layout.addWidget(self.integralArea, 2, 1, 1, 1)
        layout.addWidget(self.peakCenter, 3, 1, 1, 1)
        layout.addWidget(self.shape, 4, 1, 1, 1)
        layout.addWidget(self.algorithm, 5, 1, 1, 1)
        layout.addWidget(self.peakWidth, 6, 1, 1, 1)
        layout.addWidget(self.detectDis, 7, 1, 1, 1)
        layout.addWidget(self.noisePrt, 8, 1, 1, 1)
        layout.addWidget(self.amplitude, 9, 1, 1, 1)
        layout.addWidget(self.threshold, 10, 1, 1, 1)

        self.findBtn = QPushButton(self.translate('Find Peak'))
        layout.addWidget(self.findBtn, 11, 0, 1, 2)
        pass

    def initPlotView(self):
        self.plot = PlotWidget(enableAutoRange=True)
        self.plot.setXRange(self.lower - self.range * 0.05,
                            self.upper + self.range * 0.05)
        self.plotLegand = self.plot.addLegend()
        self.graphicsView.addWidget(self.plot)
        self.plotRegion = LinearRegionItem()
        self.plotRegion.setZValue(10)
        self.peakPoint = ScatterPlotItem(size=8,
                                         pen=mkPen(color='0000FF', width=2),
                                         symbol="+",
                                         brush=mkBrush(255, 255, 255, 240))
        self.plot.addItem(self.plotRegion, ignoreBounds=True)
        self.plot.addItem(self.peakPoint)
        self.setGraphViewStyle()

    def setGraphViewStyle(self):
        self.plot.setAutoVisible(y=True)
        self.plot.setBackground('#ffffff')
        self.plot.showGrid(x=True, y=True, alpha=0.25)
        self.plot.getAxis('bottom').setPen(color='#000000', width=1.5)
        self.plot.getAxis('left').setPen(color='#000000', width=1.5)
        self.plotRegion.setRegion([self.lower, self.upper])
        self.plotRegion.setBounds([self.lower, self.upper])

    def drawCurve(self):
        pen = mkPen(color='FF0000', width=2)
        self.plot.plot(self.x, self.y, pen=pen)
        self.plot.show()

    def translate(self, text):
        if self.parent:
            self.langText = self.parent.langText
        else:
            self.langText = load(open('SCN.translation', encoding='utf-8'))
        if text in self.langText:
            return self.langText[text]
        return text
Exemple #4
0
class TabChartView(QtWidgets.QWidget):
    """
    Виджет с графиком, стаканом и обновляющимся списком символов
    """
    def __init__(self):
        super(TabChartView, self).__init__()
        self._setup_ui()
        self._controller = TabChartController(self)

    def _setup_ui(self):
        horizontal_layout = QtWidgets.QHBoxLayout(self)

        # list symbols area
        label_exchange = QtWidgets.QLabel('Exchanges')
        self.exchanges_combobox = QtWidgets.QComboBox()
        self.exchanges_combobox.setCurrentIndex(0)
        label_symbols = QtWidgets.QLabel('Pairs')
        self.pairs_combobox = QtWidgets.QComboBox()
        self.tickers_table = QtWidgets.QTableView()
        self.tickers_table.setSelectionBehavior(
            Qt.QAbstractItemView.SelectRows)
        self.tickers_table.verticalHeader().close()
        self.tickers_table.setSelectionMode(
            Qt.QAbstractItemView.SingleSelection)
        self.delete_ticker_button = QtWidgets.QPushButton('Delete from list')

        vertical_layout_1 = QtWidgets.QVBoxLayout()
        vertical_layout_1.addWidget(label_exchange)
        vertical_layout_1.addWidget(self.exchanges_combobox)
        vertical_layout_1.addWidget(label_symbols)
        vertical_layout_1.addWidget(self.pairs_combobox)
        vertical_layout_1.addWidget(self.tickers_table)
        vertical_layout_1.addWidget(self.delete_ticker_button)
        horizontal_layout.addLayout(vertical_layout_1, 2)

        # table cup area
        self.depth_table = QtWidgets.QTableView()
        self.depth_table.setSelectionMode(
            Qt.QAbstractItemView.SelectionMode.NoSelection)
        self.depth_table.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.Stretch)
        self.depth_table.verticalHeader().close()
        horizontal_layout.addWidget(self.depth_table, 2)

        # tools for chart area
        vertical_layout_2 = QtWidgets.QVBoxLayout()
        self.panel_layout = QtWidgets.QHBoxLayout()
        self.cross_hair_checkbox = QtWidgets.QCheckBox()
        self.cross_hair_checkbox.setChecked(True)
        self.cross_hair_checkbox.setText("Crosshair")
        self.panel_layout.addWidget(self.cross_hair_checkbox)
        self.autoscroll_checkbox = QtWidgets.QCheckBox()
        self.autoscroll_checkbox.setChecked(True)
        self.autoscroll_checkbox.setText("Auto-scroll")
        self.panel_layout.addWidget(self.autoscroll_checkbox)
        self.autoscale_checkbox = QtWidgets.QCheckBox()
        self.autoscale_checkbox.setChecked(True)
        self.autoscale_checkbox.setText("Auto-scaled")
        self.panel_layout.addWidget(self.autoscale_checkbox)
        self.timeframe_combobox = QtWidgets.QComboBox()
        self.panel_layout.addWidget(self.timeframe_combobox)
        self.chart_type_combobox = QtWidgets.QComboBox()
        self.panel_layout.addWidget(self.chart_type_combobox)
        vertical_layout_2.addLayout(self.panel_layout, 1)

        self.price_chart = PlotWidget()
        self.price_chart.setBackground("w")
        self.price_chart.hideButtons()
        self.price_chart.showGrid(True, True)
        self.price_chart.getPlotItem().showAxis('right')
        self.price_chart.getAxis('bottom').setStyle(showValues=False)
        self.price_chart.getAxis('left').setStyle(showValues=False)
        self.price_chart.getViewBox().setLimits(yMin=-1, xMin=-1)

        time_axis = CustomAxisItem(orientation='bottom')
        self.volume_chart = PlotWidget(axisItems={'bottom': time_axis})
        self.volume_chart.setBackground("w")
        self.volume_chart.hideButtons()
        self.volume_chart.showGrid(True, True)
        self.volume_chart.getPlotItem().showAxis('right')
        self.volume_chart.getAxis('left').setStyle(showValues=False)
        self.volume_chart.getViewBox().setLimits(yMin=-1, xMin=-1)

        self.price_chart.setXLink(self.volume_chart)

        vertical_layout_2.addWidget(self.price_chart, 4)
        vertical_layout_2.addWidget(self.volume_chart, 1)
        horizontal_layout.addLayout(vertical_layout_2, 5)
Exemple #5
0
class Design(QWidget):
    colors = {"cathode": "#FF0000", "anode": "#0000FF", "full": "#000000"}
    symbols = {"cathode": "o", "anode": "s", "full": "t"}

    def __init__(self, parent):
        super(Design, self).__init__()
        self.parent = parent
        self.core = parent.core
        self.parameters = None
        self.datas = None
        self.renderWindow()
        self.initPlotView()
        self.setUpProcessUI()
        self.bindEvents()

    def bindEvents(self):
        self.generate.clicked.connect(self.genCurve)
        self.save.clicked.connect(self.saveCurve)
        self.Sheme.currentIndexChanged.connect(self.selectScheme)
        pass

    def renderWindow(self):
        #边框结构
        self.setGeometry(80, 80, 800, 420)
        size = self.geometry()
        screen = QDesktopWidget().screenGeometry()
        posX = (screen.width() - size.width()) / 2
        posY = (screen.height() - size.height()) / 2
        self.move(posX, posY)
        #标题
        self.setWindowTitle('Designer')
        self.setWindowIcon(QIcon('resource/curve.ico'))
        #布局
        layout = QGridLayout()
        self.graphicsView = QGridLayout()
        layout.addLayout(self.graphicsView, 0, 0, 1, 1)

        self.Process_Box = QGroupBox()
        self.Process_Box.setMinimumSize(240, 440)
        self.Process_Box.setFlat(True)
        layout.addWidget(self.Process_Box, 0, 1, 1, 1)

        self.setLayout(layout)

    def setUpProcessUI(self):
        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        self.Process_Box.setLayout(layout)

        layout.addWidget(QLabel(self.translate('Standard Cathode')), 0, 0, 1,
                         3)
        layout.addWidget(QLabel(self.translate('Standard Anode')), 1, 0, 1, 3)
        layout.addWidget(QLabel(
            self.translate('Capacity Ratio of 0.01C/0.2C')), 2, 0, 1, 3)  #()
        layout.addWidget(QLabel(self.translate('Capacity of 0.2C')), 3, 0, 1,
                         3)
        layout.addWidget(QLabel(self.translate('1st Cycle Efficiency')), 4, 0,
                         1, 3)
        layout.addWidget(QLabel(self.translate('Cathode Area')), 5, 0, 1, 3)
        layout.addWidget(QLabel(self.translate('Cathode Coating Weight')), 6,
                         0, 1, 3)
        layout.addWidget(QLabel(self.translate('Cathode Loading')), 7, 0, 1, 3)
        layout.addWidget(QLabel(self.translate('Anode Coating Weight')), 8, 0,
                         1, 3)
        layout.addWidget(QLabel(self.translate("Anode Loading")), 9, 0, 1, 3)
        layout.addWidget(QLabel(self.translate("Sheme")), 10, 0, 1, 3)
        layout.addWidget(QLabel(self.translate("Discharge Start Voltage")), 11,
                         0, 1, 3)
        layout.addWidget(QLabel(self.translate("Discharge End Voltage")), 12,
                         0, 1, 3)

        self.Cathodes = QComboBox()
        self.Anodes = QComboBox()
        keys = list(self.core.datas.keys())
        keys.sort(key=lambda x: self.core.order.index(x))
        for k in keys:
            for tag in self.core.pos_tag:
                if isStartWith(k, tag):
                    self.Cathodes.addItem(k)
                    break
            for tag in self.core.neg_tag:
                if isStartWith(k, tag):
                    self.Anodes.addItem(k)
                    break
        self.Sheme = QComboBox()
        self.Sheme.addItems([
            self.translate("Discharge Start Voltage"),
            self.translate("Discharge End Voltage")
        ])
        self.Ratio = SpinBox(lower=0, upper=10, dec=4)
        self.Capacity = SpinBox(lower=0, upper=10000, val=0, dec=4)
        self.Efficiency = SpinBox(lower=0, upper=1, val=0.98, dec=4)
        self.CathodeArea = SpinBox(lower=0, upper=1E9, dec=4)
        self.CathodeCW = SpinBox(lower=0, upper=1E9, dec=4)
        self.CathodeLoading = SpinBox(lower=0, upper=1, dec=4)
        self.AnodeCW = SpinBox(lower=0, upper=1E9, dec=4)
        self.AnodeLoading = SpinBox(lower=0, upper=1, dec=4)
        self.StartVoltage = SpinBox(lower=0, upper=5, val=4.3, dec=4)
        self.EndVoltage = SpinBox(lower=0, upper=5, val=2.7, dec=4)

        layout.addWidget(self.Cathodes, 0, 3, 1, 3)
        layout.addWidget(self.Anodes, 1, 3, 1, 3)
        layout.addWidget(self.Ratio, 2, 3, 1, 3)
        layout.addWidget(self.Capacity, 3, 3, 1, 3)
        layout.addWidget(self.Efficiency, 4, 3, 1, 3)
        layout.addWidget(self.CathodeArea, 5, 3, 1, 3)
        layout.addWidget(self.CathodeCW, 6, 3, 1, 3)
        layout.addWidget(self.CathodeLoading, 7, 3, 1, 3)
        layout.addWidget(self.AnodeCW, 8, 3, 1, 3)
        layout.addWidget(self.AnodeLoading, 9, 3, 1, 3)
        layout.addWidget(self.Sheme, 10, 3, 1, 3)
        layout.addWidget(self.StartVoltage, 11, 3, 1, 3)
        layout.addWidget(self.EndVoltage, 12, 3, 1, 3)

        self.load = QPushButton(self.translate("Load"))
        self.generate = QPushButton(self.translate("Generate"))
        self.save = QPushButton(self.translate("Save"))
        self.load.setDisabled(True)
        scheme = int(self.defaultSetting("Design/Sheme", 0))
        self.Sheme.setCurrentIndex(scheme)
        self.selectScheme()
        layout.addWidget(self.load, 13, 0, 1, 2)
        layout.addWidget(self.generate, 13, 2, 1, 2)
        layout.addWidget(self.save, 13, 4, 1, 2)
        pass

    def initPlotView(self):
        self.plot = PlotWidget(enableAutoRange=True)
        self.plotLegand = self.plot.addLegend()
        self.graphicsView.addWidget(self.plot)
        self.setGraphViewStyle()

    def setGraphViewStyle(self):
        bgColor = self.defaultSetting('Graph/BackgroundColor', '#ffffff')
        gridAlpha = float(self.defaultSetting('Graph/GridAlpha', 0.25))
        axisColor = self.defaultSetting('Graph/AxisColor', '#000000')
        axisWidth = float(self.defaultSetting('Graph/AxisWidth', 1.5))
        self.plot.setAutoVisible(y=True)
        self.plot.setBackground(bgColor)
        self.plot.showGrid(x=True, y=True, alpha=gridAlpha)
        self.plot.getAxis('bottom').setPen(color=axisColor, width=axisWidth)
        self.plot.getAxis('left').setPen(color=axisColor, width=axisWidth)

    def drawCurve(self, x, y, text):
        self.plot.removeItem(text)
        curveType = self.defaultSetting('Curve/type', 'line')
        width = int(self.defaultSetting('Curve/width', 3))
        size = int(self.defaultSetting('Curve/size', 5))
        color = self.colors[text]
        symbol = self.symbols[text]
        pen = mkPen(color=color, width=width)
        text = self.translate(text)
        self.plotLegand.removeItem(text)
        if curveType == 'scatter':
            self.plot.plot(x,
                           y,
                           pen=pen,
                           symbolBrush=color,
                           symbolPen=color,
                           symbol=symbol,
                           symbolSize=size,
                           name=text)
        else:
            self.plot.plot(x, y, pen=pen, name=text)
        self.plot.show()

    def genCurve(self):
        posName = self.Cathodes.currentText()
        negName = self.Anodes.currentText()
        capacity = self.Ratio.value() * self.Capacity.value()
        posMass = self.CathodeArea.value() * self.CathodeCW.value(
        ) * self.CathodeLoading.value() / 1540.25
        negMass = self.CathodeArea.value() * self.AnodeCW.value(
        ) * self.AnodeLoading.value() / 1540.25
        efficiency = self.Efficiency.value()
        if capacity * posMass * negMass * efficiency == 0 or posName == "" or negName == "":
            self.critical("Invalid Parameters!")
            return
        posLoss = capacity * (1 / efficiency - 1)
        #print(posMass,posLoss)
        posData = self.core.get_data(posName).modify_x(posMass, 0)
        posLoss = posData.x_max - capacity - posLoss
        if posLoss < 0:
            return self.cathodeLess()
        posData = self.core.get_data(posName).modify_x(posMass, posLoss)
        #print(posMass,posLoss)
        if self.Sheme.currentIndex() == 1:
            terminal = posData.posValue(capacity)
            #print(terminal)
            if terminal == None:
                return self.cathodeLess()
            delta = terminal - self.EndVoltage.value()
            negData = self.core.get_data(negName).modify_x(negMass, 0)
            terminal = negData.invert().posValue(delta)
            if terminal == None or terminal < capacity:
                return self.anodeLess()
            negLoss = terminal - capacity
            negData = self.core.get_data(negName).modify_x(negMass, negLoss)
        else:
            terminal = posData.posValue(0)
            if terminal == None:
                return self.cathodeLess()
            delta = terminal - self.StartVoltage.value()
            negData = self.core.get_data(negName).modify_x(negMass, 0)
            #print(delta)
            terminal = negData.invert().posValue(delta)
            if terminal == None:
                return self.anodeLess()
            negLoss = terminal
            negData = self.core.get_data(negName).modify_x(negMass, negLoss)
            if negData.x_max < capacity:
                return self.anodeLess()
        fulDataX = np.linspace(0, capacity, 2000)
        fulDataY = posData.interpolate(fulDataX).y_data - negData.interpolate(
            fulDataX).y_data
        self.parameters = [posMass, posLoss, negMass, negLoss]
        self.datas = [posData, negData, posData.copy(fulDataX, fulDataY)]
        for x in self.plot.items():
            if isinstance(x, (ScatterPlotItem, PlotCurveItem, PlotDataItem)):
                self.plot.removeItem(x)
        self.drawCurve(*posData(), "cathode")
        self.drawCurve(*negData(), "anode")
        self.drawCurve(fulDataX, fulDataY, "full")

    def saveCurve(self):
        # (value, ok) = QInputDialog.getText(self, self.translate("Save Data"), self.translate("Please input data name"), QLineEdit.Normal, "")
        # if not ok:
        #     return
        # if self.parameters == None or self.datas == None:
        #     return
        # if value == "":
        #     self.critical("Data name can not be empty string!")
        #     return
        # elif re.match(r'(\:|\\|\/|\*|\?|\"|<|>|\|)',value):
        #     self.critical("There are invalid characters in the data name!")
        #     return
        # if (value + "_full") in self.core.datas or (value + "_anode") in self.core.datas or (value + "_cathode") in self.core.datas:
        #     ok = self.warnning("Data with the same name already exists!\nDo you want to override old datas?")
        #     if not ok:
        #         return
        # self.core.add_data((value + "_cathode"),self.datas[0],override=True)
        # self.core.add_data((value + "_anode"),self.datas[1],override=True)
        # self.core.add_data((value + "_full"),self.datas[2],override=True)
        self.core.max_capacity = self.Ratio.value() * self.Capacity.value()
        self.parent.setSetting('Core/MaxCapacity', self.core.max_capacity)
        self.core.auto_cal_param(self.parameters[0], 0)
        self.core.auto_cal_param(self.parameters[1], 1)
        self.core.auto_cal_param(self.parameters[2], 2)
        self.core.auto_cal_param(self.parameters[3], 3)
        self.core.for_fitting = [
            self.Cathodes.currentText(),
            self.Anodes.currentText(), ""
        ]
        self.core.triggle('change')
        self.core.triggle('fitting')

    def anodeLess(self):
        self.critical(
            "The theoretical maximum anode capacity is less than the design capacity!"
        )

    def cathodeLess(self):
        self.critical(
            "The theoretical maximum cathode capacity is less than the design capacity!"
        )

    def selectScheme(self, idx=0):
        if self.Sheme.currentIndex() == 0:
            self.EndVoltage.setDisabled(True)
            self.StartVoltage.setEnabled(True)
        else:
            self.StartVoltage.setDisabled(True)
            self.EndVoltage.setEnabled(True)
        self.setSetting("Design/Sheme", self.Sheme.currentIndex())

    def translate(self, text):
        if self.parent:
            self.langText = self.parent.langText
        else:
            self.langText = load(open('SCN.translation', encoding='utf-8'))
        if text in self.langText:
            return self.langText[text]
        return text

    def defaultSetting(self, key, value):
        if self.parent:
            return self.parent.defaultSetting(key, value)
        return value

    def setSetting(self, key, value):
        if self.parent:
            return self.parent.setSetting(key, value)

    def critical(self, text):
        QMessageBox.critical(self, self.translate("Critical"),
                             self.translate(text), QMessageBox.Yes)

    def warnning(self, text):
        return QMessageBox.warning(self, self.translate("Warning"),
                                   self.translate(text),
                                   QMessageBox.No | QMessageBox.Yes)
Exemple #6
0
class Plot(QObject, Object):
    """Generic widget to plot data series. The data series have to be added
    first, then one may add plot items using two them as x and y values. The
    series will be automatically updated when the master attribute fires a
    value_changed signal or based on an internal update timer. This master
    series has to be defined while adding it.
    
    .. todo:: Currently only setting both series of a plot item to the same,
        fixed length works. Find a better handling for this.
    """
    TYPE_STATIC = 0
    TYPE_TIME = 1
    TYPE_SCALAR = 2
    TYPE_SPECTRUM = 3

    ROLE_SLAVE = 0
    ROLE_MASTER = 1

    def __init__(self, parent=None):
        """Construct a new Plot instance.
        
        :param parent: Optional, but needed for painting.
        :type parent: QGraphicsItem
        """
        QObject.__init__(self)
        Object.__init__(self)
        self.parent = parent
        self.lines = {}
        self.items = {}  #plot items
        self.data = {}  #data series to the plot items
        self.master = None  #id of the data series which triggers the update
        self.x_range = -1  #id of the data series which range defines the plot range
        self.mutex = QMutex()
        self.update_timer = QTimer(self)
        self.update_timer_start = None
        self.setup_ui()

    def setup_ui(self):
        """Setup the internal widget object. Called by :func:`__init__()`."""
        self.widget = PlotWidget(self.parent)
        self.widget.setBackgroundBrush(QBrush(Qt.NoBrush))
        count = len(self.janus.widgets["mainwindow"].findChildren(PlotWidget))
        self.widget.setObjectName("plotWidgetPlot{0}".format(count))
        self.widget.getAxis("bottom").setPen(QPen(Qt.black))
        self.widget.getAxis("left").setPen(QPen(Qt.black))

    def update_values(self, attribute=None):
        """Update all data of TYPE_TIME, TYPE_SCALAR, TYPE_SPECTRUM and plot it.

        This method is connected to either the the value_changed signal of the
        device instance that the master attribute belongs to or the internal
        update_timer if the master is of TYPE_TIME. 

        :param attribute: Name of the master attribute
            which triggered the update or None if master is of TYPE_TIME.
        :type attribute: str|None
        """
        self.mutex.lock()
        if not ((attribute is None and \
                self.data[self.master]["data_type"] == Plot.TYPE_TIME) or \
                (attribute == self.data[self.master]["name"] and \
                self.data[self.master]["data_type"] in \
                [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM])):
            self.mutex.unlock()
            return
        if self.update_timer_start is not None:
            time_stamp = time.time() - self.update_timer_start
        update = len(self.items) * [False]
        #retrieve new data and cycle the buffer if max_length is reached
        for i in range(len(self.data)):
            if self.data[i]["data_type"] == Plot.TYPE_TIME:
                if self.data[i]["data"].shape[0] > self.data[i]["max_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
                if self.data[i]["data"].shape[0] == self.data[i]["max_length"]:
                    self.data[i]["data"] = numpy.concatenate( \
                            (self.data[i]["data"][1:], self.data[i]["data"][:1]))
                    self.data[i]["data"][-1] = time_stamp
                else:
                    numpy.concatenate(self.data[i]["data"], time_stamp)
            elif self.data[i]["data_type"] == Plot.TYPE_SCALAR:
                if self.data[i]["data"].shape[0] > self.data[i]["max_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
                if self.data[i]["data"].shape[0] == self.data[i]["max_length"]:
                    self.data[i]["data"] = numpy.concatenate( \
                            (self.data[i]["data"][1:], self.data[i]["data"][:1]))
                    self.data[i]["data"][-1] = self.data[i]["getter"](
                        refresh=True)
                else:
                    numpy.concatenate(self.data[i]["data"], \
                            self.data[i]["getter"](refresh=True))
            elif self.data[i]["data_type"] == Plot.TYPE_SPECTRUM:
                self.data[i]["data"] = numpy.ndarray(
                    self.data[i]["getter"](refresh=True))
                if self.data[i]["data"].shape[0] >= self.data[i]["max_length"] or \
                        self.data[i]["data"].shape[0] < self.data[i]["min_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
            else:
                continue
            for item in self.data[i]["items"]:
                update[item] = True
        #set view boundaries if tie_x_range is set to a dataset
        if self.x_range > -1:
            if self.data[self.x_range]["data_type"] == Plot.TYPE_TIME:
                self.widget.setLimits( \
                        xMin=self.data[self.x_range]["data"][1], \
                        xMax=self.data[self.x_range]["data"][-1])
            else:
                self.widget.setLimits( \
                        xMin=numpy.amin(self.data[self.x_range]["data"]), \
                        xMax=numpy.amax(self.data[self.x_range]["data"]))
        #replot items
        for i in range(len(self.items)):
            if update[i]:
                self.items[i]["plot"].setData( \
                        self.data[self.items[i]["x"]]["data"], \
                        self.data[self.items[i]["y"]]["data"])
        self.mutex.unlock()

    def add_plot_data(self, i, data=None, attr=None, data_type=TYPE_STATIC, \
                role=ROLE_SLAVE, interval=1.0, \
                min_length=0, length=-1, max_length=-1):
        """Add a data series to the plot.
        
        :param i: Id of the data series. Should be ascending natural numbers 
            from 0 up.
        :type i: int
        :param data: Initial series of values. May be omited if not of
            TYPE_STATIC.
        :type data: numpy.ndarray|None
        :param attr: Reference to the getter function for an attribute of an
            device object. May be omited if not of TYPE_SCALAR or TYPE_SPECTRUM.
        :type attr: Device.method
        :param data_type: How the data is updated. May be one of the following 
            - TYPE_STATIC no update,
            - TYPE_TIME append time stamp at trigger point,
            - TYPE_SCALAR append attribute value at trigger point,
            - or TYPE_SPECTRUM exchange data series by attribute values at
                trigger point.
        :type data_type: int|TYPE_STATIC|TYPE_TIME|TYPE_SCALAR|TYPE_SPECTRUM
        :param role: Should be ROLE_MASTER for data series which triggers the
            plot update.
        :type role: int|ROLE_SLAVE|ROLE_MASTER
        :param interval: Interval, to which the update_timer is set if of
            TYPE_TIME and ROLE_MASTER. May be omited otherwise.
        :type interval: float
        :param min_length: Data series will be extended to this length. May be
            omited.
        :type min_length: int
        :param length: Sets min_length and max_length to this value. -1 will
            will disable this feature. May be omited.
        :type length: int
        :param max_length: Data series will be shortened to this length. -1 will
            will disable this feature. May be omited.
        :type max_length: int
        :return: False on errors, True otherwise.
        :rtype: bool
        """
        if length > -1:
            min_length = length
            max_length = length
        if data is not None and type(data) != numpy.ndarray:
            data = numpy.array(data)
        if data is not None and data.shape[0] < min_length:
            data.resize(min_length)
        if data is not None and max_length > 0 and data.shape[0] > max_length:
            data.resize(max_length)
        datum = { \
                "data": data, \
                "data_type": data_type, \
                "min_length": min_length, \
                "length": length, \
                "max_length": max_length, \
                "items" : []}
        if data_type in [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            try:
                if callable(attr):
                    device = attr.__self__
                    name = attr.__name__
                else:
                    return False
            except:
                return False
            datum["device"] = device  #device instance
            datum["name"] = name  #attribute name
            datum["getter"] = attr  #attribute getter method
            if data is None and data_type == Plot.TYPE_SCALAR:
                start_value = attr(refresh=True)
                datum["data"] = numpy.full(min_length, start_value)
            elif data is None:
                datum["data"] = numpy.array(attr(refresh=True))
                if datum["data"].shape[0] < min_length:
                    datum["data"].resize(min_length)
                if max_length > 0 and datum["data"].shape[0] > max_length:
                    datum["data"].resize(max_length)
        elif data_type == Plot.TYPE_TIME:
            datum["interval"] = interval
            if data is None:
                datum["data"] = numpy.linspace( \
                        -(min_length-1)*interval, 0, min_length)
        elif data_type != Plot.TYPE_STATIC:
            return False
        self.mutex.lock()
        self.data[i] = datum
        self.mutex.unlock()
        if role == Plot.ROLE_MASTER:
            self.set_master(i)
        return True

    def remove_plot_data(self, i):
        if i == self.master:
            self.unset_master()
        items = self.data[i]["items"]
        for item in items:
            self.remove_plot_item(item)
        del self.data[i]

    def add_plot_item(self, i, x, y, colour=Qt.red):
        """Add a plot item representing two already added data series.
        
        :param i: Id of the plot item. Should be ascending natural numbers 
            from 0 up.
        :type i: int
        :param x: Id of the data series holding the x values.
        :type x: int
        :param y: Id of the data series holding the y values.
        :type y: int
        :param colour: Colour of the plot item. The default is red.
        :type colour: str|QRgb|QColor|Qt.GlobalColor
        """
        self.items[i] = {"x": x, "y": y}
        self.data[x]["items"].append(i)
        self.data[y]["items"].append(i)
        self.items[i]["plot"] = PlotDataItem( \
                self.data[x]["data"], \
                self.data[y]["data"], \
                pen=QColor(colour))
        self.widget.addItem(self.items[i]["plot"])

    def remove_plot_item(self, i):
        self.mutex.lock()
        self.data[self.items[i]["x"]]["items"].remove(i)
        self.data[self.items[i]["y"]]["items"].remove(i)
        self.widget.removeItem(self.items[i]["plot"])
        del self.items[i]
        self.mutex.unlock()

    def add_line_item(self, i, **kwargs):
        self.mutex.lock()
        self.lines[i] = InfiniteLine(**kwargs)
        self.widget.addItem(self.lines[i])
        self.mutex.unlock()

    def remove_line_item(self, i):
        self.mutex.lock()
        self.widget.removeItem(self.lines[i])
        del self.lines[i]
        self.mutex.unlock()

    def set_master(self, i):
        """Set which data series will trigger a plot update.
        
        :param data: Id of the data series which triggers the update.
        :type data: int
        """
        self.mutex.lock()
        if self.master is not None and self.master != i:
            self.unset_master()
            self.data[i]["device"].value_changed.disconnect(self.update_values)
        if self.data[i]["data_type"] in [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            self.data[i]["device"].value_changed.connect(self.update_values)
        elif self.data[i]["data_type"] == Plot.TYPE_TIME:
            self.update_timer.timeout.connect(self.update_values)
            self.update_timer_start = time.time()
            self.update_timer.start(self.data[i]["interval"] * 1000.)
        self.master = i
        self.mutex.unlock()

    def unset_master(self):
        self.mutex.lock()
        if self.data[self.master]["data_type"] in \
                [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            self.data[self.master]["device"].value_changed.disconnect( \
                    self.update_values)
        elif self.data[self.master]["data_type"] == Plot.TYPE_TIME:
            self.update_timer.timeout.disconnect(self.update_values)
            self.update_timer.stop()
        self.mutex.unlock()

    def tie_x_range(self, data=-1):
        """Sets the plot x range to be the same as the given data series.
        
        :param data: Id of the data series holding the x values.
        :type data: int
        """
        self.x_range = data

    def clear(self):
        data = list(self.data.keys())
        for datum in data:
            self.remove_plot_data(datum)
        for line in list(self.lines.keys()):
            self.remove_line_item(line)
Exemple #7
0
class StatsWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.setGeometry(150 + 1024, 150, 800, 600)

        main_box = QVBoxLayout()

        self.graph_rfi = PlotWidget()
        self.graph_rfi.setBackground("w")
        self.graph_rfi.setTitle("RFI", color="k")
        self.graph_rfi.plot = self.graph_rfi.plot([0,0], [0],
                                                  pen=mkPen('k', width=1),
                                                  stepMode=True)
        self.graph_cand = PlotWidget()
        self.graph_cand.setBackground("w")
        self.graph_cand.setTitle("Candidates", color="k")
        self.graph_cand.plot = self.graph_cand.plot([0,0], [0],
                                                  pen=mkPen('k', width=1),
                                                  stepMode=True)

        self.dist_plot = PlotWidget()
        self.dist_plot.setMouseEnabled(y=False)
        self.dist_plot.setBackground("w")
        self.dist_plot.setTitle("Full distribution", color="k")
        self.dist_plot.plot = self.dist_plot.plot([0,0], [0],
                                                  pen=mkPen('k', width=1),
                                                  stepMode=True)


        plots_box = QHBoxLayout()
        plots_box.addWidget(self.graph_rfi)
        plots_box.addWidget(self.graph_cand)
        main_box.addLayout(plots_box)
        main_box.addWidget(self.dist_plot)

        limits_box = QHBoxLayout()
        limits_box.setAlignment(Qt.AlignLeft)
        
        self.limits_choice = QComboBox()
        self.limits_choice.addItems(["DM", "MJD"])
        self.limits_choice.setFixedWidth(100)
        limits_box.addWidget(self.limits_choice)
        self.start_limit = QLineEdit()
        self.start_limit.setPlaceholderText("from")
        self.start_limit.setFixedWidth(150)
        limits_box.addWidget(self.start_limit)
        self.end_limit = QLineEdit()
        self.end_limit.setPlaceholderText("to")
        self.end_limit.setFixedWidth(150)
        limits_box.addWidget(self.end_limit)
        self.apply_limits_button = QPushButton()
        self.apply_limits_button.setFixedWidth(150)
        self.apply_limits_button.setText("Remove limits")
        limits_box.addWidget(self.apply_limits_button)
        self.remove_label = QLabel()
        limits_box.addWidget(self.remove_label)
        main_box.addLayout(limits_box)
        

        self.setLayout(main_box)

    def _update(self, rfi_data, cand_data):

        y_rfi, x_rfi = histogram([cand[1] for cand in rfi_data],
                                 bins=min(len(rfi_data) + 1, 100))
        self.graph_rfi.plot.setData(x_rfi, y_rfi)

        y_cand, x_cand = histogram([cand[1] for cand in cand_data],
                                   bins=min(len(cand_data) + 1, 100))
        self.graph_cand.plot.setData(x_cand, y_cand)

    def update_dist_plot(self, data, extra_dec=False):

        y_dist, x_dist = histogram(data, bins=100)
        ax = self.dist_plot.getAxis("bottom")

        min_val = min(data)
        max_val = max(data)
        tick_vals = linspace(min_val, max_val, num=6)
        decimals = 2 + extra_dec * 4
        ticks = [(val, "{:.{dec}f}".format(val, dec=decimals)) for val in tick_vals]
        ax.setTicks( [ticks, []])
        ax.setStyle(tickLength=-5)
        self.dist_plot.plot.setData(x_dist, y_dist)
        self.dist_plot.autoRange()
Exemple #8
0
class Ui_CovidTracker(object):
    def setupUi(self, CovidTracker):
        CovidTracker.setObjectName("CovidTracker")
        CovidTracker.resize(988, 823)
        self.centralwidget = QtWidgets.QWidget(CovidTracker)
        self.centralwidget.setObjectName("centralwidget")

        #plot tab
        self.plot_tab = QtWidgets.QTabWidget(self.centralwidget)
        self.plot_tab.setGeometry(QtCore.QRect(10, 310, 971, 451))
        self.plot_tab.setObjectName("plot_tab")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.graphicsView = PlotWidget(self.tab)
        self.graphicsView.setGeometry(QtCore.QRect(0, 0, 961, 421))
        self.graphicsView.setObjectName("graphicsView")
        self.plot_tab.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.graphicsView_2 = PlotWidget(self.tab_2)
        self.graphicsView_2.setGeometry(QtCore.QRect(0, 0, 961, 421))
        self.graphicsView_2.setObjectName("graphicsView_2")
        self.plot_tab.addTab(self.tab_2, "")

        # self.plot_tab.addTab(self.tab, "")
        # self.tab_3 = QtWidgets.QWidget()
        # self.tab_3.setObjectName("tab_3")
        # self.graphicsView_3 = GraphicsLayoutWidget(self.tab_3)
        # self.graphicsView_3.setGeometry(QtCore.QRect(0, 0, 961, 421))
        # self.graphicsView_3.setObjectName("graphicsView_3")
        # self.plot_tab.addTab(self.tab_3, "")

        #country name
        self.country_name = QtWidgets.QLineEdit(self.centralwidget)
        self.country_name.setGeometry(QtCore.QRect(850, 150, 113, 22))
        self.country_name.setObjectName("country_name")

        #track button
        self.track_button = QtWidgets.QPushButton(self.centralwidget)
        self.track_button.setGeometry(QtCore.QRect(850, 180, 111, 31))
        self.track_button.setObjectName("track_button")
        self.track_button.clicked.connect(self.get_covid)

        #speak button
        self.speak_button = QtWidgets.QPushButton(self.centralwidget)
        self.speak_button.setGeometry(QtCore.QRect(850, 220, 111, 28))
        self.speak_button.setObjectName("speak_button")
        self.speak_button.clicked.connect(self.start_record)

        #reset button
        self.reset_button = QtWidgets.QPushButton(self.centralwidget)
        self.reset_button.setGeometry(QtCore.QRect(850, 260, 111, 28))
        self.reset_button.setObjectName("reset_button")
        self.reset_button.clicked.connect(self.reset_covid)

        #data_table
        self.data_table = QtWidgets.QTableWidget(self.centralwidget)
        self.data_table.setGeometry(QtCore.QRect(10, 150, 441, 141))
        self.data_table.setObjectName("data_table")
        self.data_table.setColumnCount(4)
        self.data_table.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.data_table.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.data_table.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.data_table.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.data_table.setHorizontalHeaderItem(3, item)

        #progress bar
        self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(10, 770, 961, 23))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.progressBar.setMaximum(100)

        # plot type combo
        self.plot_type = QtWidgets.QComboBox(self.centralwidget)
        self.plot_type.setGeometry(QtCore.QRect(850, 120, 111, 22))
        self.plot_type.setObjectName("plot_type")
        self.plot_type.addItem("")
        self.plot_type.addItem("")
        self.plot_type.addItem("")
        self.plot_type.addItem("")

        #dark_light combo
        self.dark_light = QtWidgets.QComboBox(self.centralwidget)
        self.dark_light.setGeometry(QtCore.QRect(850, 90, 111, 22))
        self.dark_light.setObjectName("dark_light")
        self.dark_light.addItem("")
        self.dark_light.addItem("")
        self.dark_light.currentIndexChanged.connect(self.mode_change)

        #animated checkbox
        self.animated_checkbox = QtWidgets.QCheckBox(self.centralwidget)
        self.animated_checkbox.setGeometry(QtCore.QRect(870, 300, 101, 20))
        self.animated_checkbox.setObjectName("animated_checkbox")
        #self.animated_checkbox.stateChanged.connect(self.check_box_state_change)
        # simple horizontal line
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setGeometry(QtCore.QRect(10, 290, 951, 16))
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")

        # history log box
        self.text_holder = QtWidgets.QTextBrowser(self.centralwidget)
        self.text_holder.setGeometry(QtCore.QRect(465, 151, 371, 141))
        self.text_holder.setObjectName("text_holder")

        # main label
        self.main_label = QtWidgets.QLabel(self.centralwidget)
        self.main_label.setGeometry(QtCore.QRect(400, 30, 261, 41))
        font = QtGui.QFont()
        font.setFamily("Jokerman")
        font.setPointSize(14)
        self.main_label.setFont(font)
        self.main_label.setObjectName("main_label")

        # history label
        self.history_label = QtWidgets.QLabel(self.centralwidget)
        self.history_label.setGeometry(QtCore.QRect(500, 130, 71, 16))
        self.history_label.setObjectName("history_label")

        # data label
        self.data_label = QtWidgets.QLabel(self.centralwidget)
        self.data_label.setGeometry(QtCore.QRect(10, 130, 71, 16))
        self.data_label.setObjectName("data_label")

        CovidTracker.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(CovidTracker)
        self.statusbar.setObjectName("statusbar")
        CovidTracker.setStatusBar(self.statusbar)

        self.retranslateUi(CovidTracker)
        self.plot_tab.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(CovidTracker)

        self.df = df_covid_2019
        self.country_list = self.df['countriesAndTerritories']
        self.color_list = ((255, 255, 255), (255, 0, 0), (0, 255, 0),
                           (0, 0, 255), (255, 255, 0), (0, 255, 255), (255, 0,
                                                                       255))
        self.num_iter = 0
        self.data_table_num = 0
        self.start_covid()

    def retranslateUi(self, CovidTracker):
        _translate = QtCore.QCoreApplication.translate
        CovidTracker.setWindowTitle(_translate("CovidTracker",
                                               "Covid Tracker"))
        self.plot_tab.setTabText(self.plot_tab.indexOf(self.tab),
                                 _translate("CovidTracker", "Plot 1"))
        self.plot_tab.setTabText(self.plot_tab.indexOf(self.tab_2),
                                 _translate("CovidTracker", "Plot 2"))
        #self.plot_tab.setTabText(self.plot_tab.indexOf(self.tab_3), _translate("CovidTracker", "Chart"))
        self.track_button.setText(_translate("CovidTracker", "Track!"))
        self.speak_button.setText(_translate("CovidTracker", "Speak!"))
        self.reset_button.setText(_translate("CovidTracker", "Reset!"))
        self.plot_type.setItemText(0, _translate("CovidTracker", "Infections"))
        self.plot_type.setItemText(1,
                                   _translate("CovidTracker", "deaths_weekly"))
        self.plot_type.setItemText(2, _translate("CovidTracker", "Cumulative"))
        self.plot_type.setItemText(3, _translate("CovidTracker", "Comparison"))
        self.dark_light.setItemText(0, _translate("CovidTracker", "Dark"))
        self.dark_light.setItemText(1, _translate("CovidTracker", "Light"))
        # item = self.data_table.horizontalHeaderItem(0)
        # item.setText(_translate("CovidTracker", "Date"))
        # item = self.data_table.horizontalHeaderItem(1)
        # item.setText(_translate("CovidTracker", "Number"))
        # item = self.data_table.horizontalHeaderItem(2)
        # item.setText(_translate("CovidTracker", "Date"))
        # item = self.data_table.horizontalHeaderItem(3)
        # item.setText(_translate("CovidTracker", "Number"))
        self.animated_checkbox.setText(_translate("CovidTracker", "Animated"))
        self.main_label.setText(_translate("CovidTracker", "COVID-19 Tracker"))
        self.history_label.setText(_translate("CovidTracker", "History Log :"))
        self.data_label.setText(_translate("CovidTracker", "Data"))

    def covid_plot(self):
        ui.progressBar.setValue(0)
        self.num_iter = self.num_iter + 1
        self.data_table_num = self.data_table_num + 2
        if self.num_iter > 6:
            self.num_iter = 0
        self.country_input = self.country_name.text()
        if self.country_input == None or self.country_input == '' or self.country_input == 'None Selected':
            self.country_input = random.choice(np.array(self.country_list))
        self.country_input = self.country_input.replace(' ', '_')

        if self.country_input in set(self.country_list):
            pass
        else:
            self.text_holder.append(
                'Country Not found. Choosing Random Country.')
            self.country_input = random.choice(np.array(self.country_list))
        self.country_name.setText(self.country_input.replace('_', ' '))
        self.text_holder.append(datetime.datetime.now().strftime("%I:%M:%S") +
                                ' : Selected country is ' + self.country_input)
        self.cases_weekly = np.array(
            self.df[self.df['countriesAndTerritories'] ==
                    self.country_input]['cases_weekly'])[::-1]
        self.dates = np.array(self.df[self.df['countriesAndTerritories'] ==
                                      self.country_input]['dateRep'])[::-1]
        self.deaths_weekly = np.array(
            self.df[self.df['countriesAndTerritories'] ==
                    self.country_input]['deaths_weekly'])[::-1]
        self.cumulative = np.array(
            self.df[self.df['countriesAndTerritories'] == self.country_input]
            ['notification_rate_per_100000_population_14-days'])[::-1]

        if self.plot_type.currentIndex() == 0:

            #main_plot
            axis_bottom = self.graphicsView.getAxis('bottom')
            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting Infections')
            self.graphicsView.clear()
            self.x_cases_weekly = np.arange(0, len(self.cases_weekly))
            axis_bottom = self.graphicsView.getAxis('bottom')
            axis_bottom.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cases_weekly[0:len(self.x_cases_weekly):20],
                    self.dates[0:len(self.cases_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cases_weekly[0:len(self.cases_weekly):10])]])

            self.graphicsView.plot(self.x_cases_weekly,
                                   self.cases_weekly,
                                   pen=pg.mkPen(color=(255, 0, 0), width=2),
                                   name='cases_weekly in ' +
                                   self.country_input,
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(255, 0, 0))
            ui.progressBar.setValue(100)
            #data_table

            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('cases_weekly(' +
                                           self.country_input + ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.cases_weekly)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.cases_weekly[i])))

            #second_plot
            color = self.color_list[self.num_iter]
            axis_bottom1 = self.graphicsView_2.getAxis('bottom')
            axis_bottom1.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cases_weekly[0:len(self.x_cases_weekly):20],
                    self.dates[0:len(self.cases_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cases_weekly[0:len(self.cases_weekly):10])]])
            self.graphicsView_2.addLegend()
            self.graphicsView_2.plot(self.x_cases_weekly,
                                     self.cases_weekly,
                                     pen=pg.mkPen(color=color, width=2),
                                     name='cases_weekly in ' +
                                     self.country_input,
                                     symbol='o',
                                     symbolBrush=color)

        if self.plot_type.currentIndex() == 1:

            #main plot
            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting deaths_weekly')
            self.graphicsView.clear()
            self.x_deaths_weekly = np.arange(0, len(self.deaths_weekly))

            axis_bottom = self.graphicsView.getAxis('bottom')
            axis_bottom.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_deaths_weekly[0:len(self.x_deaths_weekly):20],
                    self.dates[0:len(self.deaths_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_deaths_weekly[0:len(self.deaths_weekly):10])]])

            self.graphicsView.plot(
                self.x_deaths_weekly,
                self.deaths_weekly,
                pen=pg.mkPen(color=(200, 200, 200), width=2),
                name='deaths_weekly in ' + self.country_input,
                symbol='o',
                symbolSize=7,
                symbolBrush=(200, 200, 200))
            ui.progressBar.setValue(100)
            #data_table
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('deaths_weekly(' +
                                           self.country_input + ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.deaths_weekly)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.deaths_weekly[i])))

            #second plot
            color = self.color_list[self.num_iter]
            axis_bottom1 = self.graphicsView_2.getAxis('bottom')
            axis_bottom1.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_deaths_weekly[0:len(self.x_deaths_weekly):20],
                    self.dates[0:len(self.deaths_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_deaths_weekly[0:len(self.deaths_weekly):10])]])
            self.graphicsView_2.addLegend()
            self.graphicsView_2.plot(self.x_deaths_weekly,
                                     self.deaths_weekly,
                                     pen=pg.mkPen(color=color, width=2),
                                     name='deaths_weekly in ' +
                                     self.country_input,
                                     symbol='o',
                                     symbolBrush=color)

        if self.plot_type.currentIndex() == 2:

            #main plot
            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting Cumulative Average of 14 days per 100000 cases_weekly'
            )
            self.graphicsView.clear()
            self.x_cumulative = np.arange(0, len(self.cumulative))

            axis_bottom = self.graphicsView.getAxis('bottom')
            axis_bottom.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cumulative[0:len(self.x_cumulative):20],
                    self.dates[0:len(self.cumulative):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cumulative[0:len(self.cumulative):10])]])
            self.graphicsView.plot(self.x_cumulative,
                                   self.cumulative,
                                   pen=pg.mkPen(color=(0, 0, 255), width=2),
                                   name='Cumulative in ' + self.country_input,
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(0, 255, 255))
            ui.progressBar.setValue(100)
            #data_table
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('Cumulative(' + self.country_input +
                                           ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.cumulative)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.cumulative[i])))

            #second plot
            color = self.color_list[self.num_iter]
            axis_bottom1 = self.graphicsView_2.getAxis('bottom')
            axis_bottom1.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cumulative[0:len(self.x_cumulative):20],
                    self.dates[0:len(self.cumulative):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cumulative[0:len(self.cumulative):10])]])
            self.graphicsView_2.addLegend()
            self.graphicsView_2.plot(self.x_cumulative,
                                     self.cumulative,
                                     pen=pg.mkPen(color=color, width=2),
                                     name='Cumulative in ' +
                                     self.country_input,
                                     symbol='o',
                                     symbolBrush=color)

        if self.plot_type.currentIndex() == 3:
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting comparison')
            self.graphicsView.clear()
            self.graphicsView.addLegend()
            self.x_cases_weekly = np.arange(0, len(self.cases_weekly))
            self.graphicsView.showGrid(x=True, y=True)

            axis_bottom = self.graphicsView.getAxis('bottom')
            axis_bottom.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cases_weekly[0:len(self.x_cases_weekly):20],
                    self.dates[0:len(self.cases_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cases_weekly[0:len(self.cases_weekly):10])]])

            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.cases_weekly),
                                   pen=(255, 0, 0),
                                   name='cases_weekly in ' +
                                   self.country_input,
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(255, 0, 0))
            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.deaths_weekly),
                                   pen=(200, 200, 200),
                                   name='deaths_weekly in ' +
                                   self.country_input,
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(200, 200, 200))
            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.cumulative),
                                   pen=(0, 0, 255),
                                   name='Cumulative in ' + self.country_input,
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(0, 0, 255))
            ui.progressBar.setValue(100)

            #data_table
            self.data_table_num = self.data_table_num + 2
            self.data_table.insertColumn(self.data_table_num - 4)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 4,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 3)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 3,
                QtWidgets.QTableWidgetItem('cases_weekly(' +
                                           self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('deaths_weekly(' +
                                           self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('Cumulative(' + self.country_input +
                                           ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 4)
            for i in range(len(self.cumulative)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 4,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 3,
                    QtWidgets.QTableWidgetItem(str(self.cases_weekly[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.deaths_weekly[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.cumulative[i])))
            #self.graphicsView.setLogMode(x=False,y=True)

        # if self.plot_type.currentIndex() == 4:
        #     self.graphicsView_3.clear()
        #     win = self.graphicsView_3
        #     pg.setConfigOptions(antialias=True)

        #     p1 = win.addPlot(title='cases_weekly')

        #     self.x_cases_weekly = np.arange(0,len(self.cases_weekly))
        #     p1.plot(self.x_cases_weekly,self.cases_weekly,pen=pg.mkPen(color=(255,0,0),width=2),name='cases_weekly in '+self.country_input,symbol='o',
        #     symbolSize=7,symbolBrush=(255,0,0))

        #     p2 = win.addPlot(title='deaths_weekly')
        #     self.x_deaths_weekly = np.arange(0,len(self.deaths_weekly))
        #     p2.plot(self.x_deaths_weekly,self.deaths_weekly,pen=pg.mkPen(color=(200,200,200), width=2),name='deaths_weekly in '+self.country_input,symbol='o',
        #     symbolSize=7,symbolBrush=(200,200,200))

        #     p3 = win.addPlot(title='Cumulative Average')
        #     self.x_cumulative = np.arange(0,len(self.cumulative))
        #     p3.plot(self.x_cumulative,self.cumulative,pen=pg.mkPen(color=(0,0,255),width=2),name='Cumulative in '+self.country_input,symbol='o',
        #     symbolSize=7,symbolBrush=(0,255,255))
        #     win.nextRow()

        #     p4 = win.addPlot(title = 'Covid Histogram')
        #     y1,x1 = np.histogram(np.hstack(self.cases_weekly),bins=int(len(self.cases_weekly)/10))
        #     p4.plot(x1,y1,stepMode=True, fillLevel=1, fillOutline=True, brush=(255,0,0,150))

    def covid_plot_anim(self):
        ui.progressBar.setValue(0)
        self.num_iter = self.num_iter + 1
        if self.num_iter > 6:
            self.num_iter = 0
        self.data_table_num = self.data_table_num + 2
        self.country_input = self.country_name.text()
        if self.country_input == None or self.country_input == '':
            self.country_input = random.choice(np.array(self.country_list))
        self.country_input = self.country_input.replace(' ', '_')

        if self.country_input in set(self.country_list):
            pass
        else:
            self.text_holder.append(
                'Country Not found. Choosing Random Country.')
            self.country_input = random.choice(np.array(self.country_list))
        self.text_holder.append(datetime.datetime.now().strftime("%I:%M:%S") +
                                ' : Selected country is ' + self.country_input)
        self.cases_weekly = np.array(
            self.df[self.df['countriesAndTerritories'] ==
                    self.country_input]['cases_weekly'])[::-1]
        self.dates = np.array(self.df[self.df['countriesAndTerritories'] ==
                                      self.country_input]['dateRep'])[::-1]
        self.deaths_weekly = np.array(
            self.df[self.df['countriesAndTerritories'] ==
                    self.country_input]['deaths_weekly'])[::-1]
        self.cumulative = np.array(
            self.df[self.df['countriesAndTerritories'] == self.country_input]
            ['notification_rate_per_100000_population_14-days'])[::-1]
        self.graphicsView.clear()

        if self.plot_type.currentIndex() == 0:

            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting Infections')
            self.graphicsView.clear()
            self.x_cases_weekly = np.arange(0, len(self.cases_weekly))
            self.x = []
            self.y = []
            #data table
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('deaths_weekly(' +
                                           self.country_input + ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.deaths_weekly)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.deaths_weekly[i])))
            for i in range(len(self.cases_weekly)):
                ui.progressBar.setValue(
                    np.linspace(0, 100, len(self.cases_weekly))[i])
                self.graphicsView.clear()
                self.x.append(self.x_cases_weekly[i])
                self.y.append(self.cases_weekly[i])
                self.graphicsView.plot(
                    self.x,
                    self.y,
                    pen=pg.mkPen(color=(255, 0, 0), width=2),
                    name='cases_weekly in ' + self.country_input,
                    symbol='o',
                    symbolSize=7,
                    symbolBrush=(255, 0, 0))
                pg.QtGui.QApplication.processEvents()
            #second_plot
            color = self.color_list[self.num_iter]
            axis_bottom1 = self.graphicsView_2.getAxis('bottom')
            axis_bottom1.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_cases_weekly[0:len(self.x_cases_weekly):20],
                    self.dates[0:len(self.cases_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_cases_weekly[0:len(self.cases_weekly):10])]])
            self.graphicsView_2.addLegend()
            self.graphicsView_2.plot(self.x_cases_weekly,
                                     self.cases_weekly,
                                     pen=pg.mkPen(color=color, width=2),
                                     name='cases_weekly in ' +
                                     self.country_input,
                                     symbol='o',
                                     symbolBrush=color)

        if self.plot_type.currentIndex() == 1:
            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting deaths_weekly')
            self.graphicsView.clear()
            self.x_deaths_weekly = np.arange(0, len(self.deaths_weekly))
            self.x = []
            self.y = []

            #data_table
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('deaths_weekly(' +
                                           self.country_input + ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.deaths_weekly)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.deaths_weekly[i])))

            #main_anim_plot
            for i in range(len(self.deaths_weekly)):
                ui.progressBar.setValue(
                    np.linspace(0, 100, len(self.deaths_weekly))[i])
                self.graphicsView.clear()
                self.x.append(self.x_deaths_weekly[i])
                self.y.append(self.deaths_weekly[i])
                self.graphicsView.plot(self.x,
                                       self.y,
                                       pen=pg.mkPen(color=(200, 200, 200),
                                                    width=2),
                                       name='deaths_weekly in ' +
                                       self.country_input,
                                       symbol='o',
                                       symbolSize=7,
                                       symbolBrush=(200, 200, 200))
                pg.QtGui.QApplication.processEvents()

            #second plot
            color = self.color_list[self.num_iter]
            axis_bottom1 = self.graphicsView_2.getAxis('bottom')
            axis_bottom1.setTicks(
                [[(i, j) for i, j in zip(
                    self.x_deaths_weekly[0:len(self.x_deaths_weekly):20],
                    self.dates[0:len(self.deaths_weekly):20])],
                 [(i, '') for j, i in enumerate(
                     self.x_deaths_weekly[0:len(self.deaths_weekly):10])]])
            self.graphicsView_2.addLegend()
            self.graphicsView_2.plot(self.x_deaths_weekly,
                                     self.deaths_weekly,
                                     pen=pg.mkPen(color=color, width=2),
                                     name='deaths_weekly in ' +
                                     self.country_input,
                                     symbol='o',
                                     symbolBrush=color)

        if self.plot_type.currentIndex() == 2:
            self.graphicsView.addLegend()
            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting Cumulative Average of 14 days per 100000 cases_weekly'
            )
            self.graphicsView.clear()
            self.x_cumulative = np.arange(0, len(self.cumulative))
            self.x = []
            self.y = []
            #data_table
            self.data_table.insertColumn(self.data_table_num - 2)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 2,
                QtWidgets.QTableWidgetItem('Date(' + self.country_input + ')'))
            self.data_table.insertColumn(self.data_table_num - 1)
            self.data_table.setHorizontalHeaderItem(
                self.data_table_num - 1,
                QtWidgets.QTableWidgetItem('Cumulative(' + self.country_input +
                                           ')'))
            self.data_table.setCurrentCell(0, self.data_table_num - 2)
            for i in range(len(self.cumulative)):

                rowPosition = self.data_table.rowCount()
                self.data_table.insertRow(rowPosition)
                self.data_table.setItem(
                    i, self.data_table_num - 2,
                    QtWidgets.QTableWidgetItem(str(self.dates[i])))
                self.data_table.setItem(
                    i, self.data_table_num - 1,
                    QtWidgets.QTableWidgetItem(str(self.cumulative[i])))

            for i in range(len(self.cumulative)):
                ui.progressBar.setValue(
                    np.linspace(0, 100, len(self.cumulative))[i])
                self.graphicsView.clear()
                self.x.append(self.x_cumulative[i])
                self.y.append(self.cumulative[i])
                self.graphicsView.plot(
                    self.x,
                    self.y,
                    pen=pg.mkPen(color=(0, 0, 255), width=2),
                    name='Cumulative in ' + self.country_input,
                    symbol='o',
                    symbolSize=7,
                    symbolBrush=(0, 255, 255))
                pg.QtGui.QApplication.processEvents()

        if self.plot_type.currentIndex() == 3:

            self.text_holder.append(
                datetime.datetime.now().strftime("%I:%M:%S") +
                ' : Plotting comparison. No animation.')
            self.graphicsView.clear()
            self.graphicsView.addLegend()
            self.x_cases_weekly = np.arange(0, len(self.cases_weekly))
            self.graphicsView.showGrid(x=True, y=True)
            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.cases_weekly),
                                   pen=(255, 0, 0),
                                   name='cases_weekly',
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(255, 0, 0))
            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.deaths_weekly),
                                   pen=(200, 200, 200),
                                   name='deaths_weekly',
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(200, 200, 200))
            self.graphicsView.plot(self.x_cases_weekly,
                                   abs(self.cumulative),
                                   pen=(0, 0, 255),
                                   name='Cumulative',
                                   symbol='o',
                                   symbolSize=7,
                                   symbolBrush=(0, 0, 255))
            ui.progressBar.setValue(100)
            #self.graphicsView.setLogMode(x=False,y=True)

        if self.plot_type.currentIndex() == 4:
            self.x_cases_weekly = np.arange(0, len(self.cases_weekly))
            self.graphicsView.plot(self.x_cases_weekly, self.cases_weekly)

    def get_covid(self):
        if self.animated_checkbox.checkState() == False:
            self.covid_plot()
        else:
            self.covid_plot_anim()

    def reset_covid(self):
        self.text_holder.setText('')
        self.graphicsView.clear()
        self.graphicsView_2.clear()
        self.data_table.clear()
        self.data_table_num = 0
        self.num_iter = 0
        self.animated_checkbox.setCheckState(False)
        self.country_name.setText('None Selected')
        self.text_holder.append(datetime.datetime.now().strftime("%I:%M:%S") +
                                ' : Covid Tracker reset!')

    def start_record(self):
        self.text_holder.append(
            datetime.datetime.now().strftime("%I:%M:%S") +
            ': \n>>>>>><<<<<<\nVoice mode activated\n>>>>>><<<<<<\nListening for 5 seconds....'
        )
        self.text_holder.repaint()
        self.record_covid()
        self.text_holder.append('Voice mode deactivated.')

    def record_covid(self):

        df = df_covid_2019

        fs = 44100  # Sample rate
        seconds = 5  # Duration of recording

        myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)

        sd.wait()  # Wait until recording is finished
        y = (np.iinfo(np.int32).max *
             (myrecording / np.abs(myrecording).max())).astype(np.int32)

        wavfile.write('output.wav', fs, y)
        r = sr.Recognizer()

        # Reading Audio file as source
        # listening the audio file and store in audio_text variable

        with sr.AudioFile('output.wav') as source:

            audio_text = r.listen(source)

            # recoginize_() method will throw a request error if the API is unreachable, hence using exception handling
            try:

                # using google speech recognition
                text = r.recognize_google(audio_text)
                self.text_holder.append(
                    datetime.datetime.now().strftime("%I:%M:%S") +
                    ": I guess you said '" + text + "'")

            except:
                self.text_holder.append(
                    datetime.datetime.now().strftime("%I:%M:%S") +
                    ': Sorry, the speech transcription service did not respond, Try again in a few minutes or type the country name.'
                )

            try:

                if text == None:
                    self.text_holder.append('Nothin recorded')
                if text.lower() == 'infections':
                    self.plot_type.setCurrentIndex(0)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Selecting plot type > Infections'
                    )
                elif text.lower() == 'deaths_weekly' or text.lower(
                ) == 'death':
                    self.plot_type.setCurrentIndex(1)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Selecting plot type > deaths_weekly'
                    )
                elif text.lower() == 'cumulative':
                    self.plot_type.setCurrentIndex(2)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Selecting plot type > Cumulative'
                    )
                elif text.lower() == 'comparison' or text.lower(
                ) == 'comparisons':
                    self.plot_type.setCurrentIndex(3)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Selecting plot type > Comparison'
                    )
                elif text.lower() == 'chart':
                    self.plot_type.setCurrentIndex(4)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Selecting plot type > Chart')
                elif text.lower() == 'reset':
                    self.reset_button.click()
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Reset Covid Tracker')
                elif text.lower() == 'dark':
                    self.dark_light.setCurrentIndex(0)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Setting Dark Mode')
                elif text.lower() == 'light':
                    self.dark_light.setCurrentIndex(1)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Setting Light Mode')
                elif text.lower() == 'animated':
                    self.animated_checkbox.setCheckState(True)
                else:
                    self.country_name.setText(text)
                    self.text_holder.append(
                        datetime.datetime.now().strftime("%I:%M:%S") +
                        ' : From voice commands : Country selected > ' + text)
                    country_name = text.replace(' ', '_')
                    if country_name in set(self.df['countriesAndTerritories']):
                        self.track_button.click()
            except UnboundLocalError:
                self.text_holder.append(
                    datetime.datetime.now().strftime("%I:%M:%S") +
                    ': Nothing was recorded')

    def mode_change(self):
        if self.dark_light.currentIndex() == 0:

            app.setStyle('Fusion')
            palette = QtGui.QPalette()
            palette.setColor(QtGui.QPalette.Window, QtGui.QColor(53, 53, 53))
            palette.setColor(QtGui.QPalette.WindowText, QtCore.Qt.white)
            palette.setColor(QtGui.QPalette.Base, QtGui.QColor(15, 15, 15))
            palette.setColor(QtGui.QPalette.AlternateBase,
                             QtGui.QColor(53, 53, 53))
            palette.setColor(QtGui.QPalette.ToolTipBase, QtCore.Qt.white)
            palette.setColor(QtGui.QPalette.ToolTipText, QtCore.Qt.white)
            palette.setColor(QtGui.QPalette.Text, QtCore.Qt.white)
            palette.setColor(QtGui.QPalette.Button, QtGui.QColor(53, 53, 53))
            palette.setColor(QtGui.QPalette.ButtonText, QtCore.Qt.white)
            palette.setColor(QtGui.QPalette.BrightText, QtCore.Qt.red)

            palette.setColor(QtGui.QPalette.Highlight,
                             QtGui.QColor(0, 67, 202, 200).lighter())
            palette.setColor(QtGui.QPalette.HighlightedText, QtCore.Qt.black)
            app.setPalette(palette)

        if self.dark_light.currentIndex() == 1:
            app.setStyle('Fusion')
            palette = QtGui.QPalette()
            palette.setColor(QtGui.QPalette.Window,
                             QtGui.QColor(255, 255, 255))
            palette.setColor(QtGui.QPalette.WindowText, QtCore.Qt.black)
            palette.setColor(QtGui.QPalette.Base, QtGui.QColor(255, 255, 255))
            palette.setColor(QtGui.QPalette.AlternateBase,
                             QtGui.QColor(246, 246, 246))
            palette.setColor(QtGui.QPalette.ToolTipBase, QtCore.Qt.black)
            palette.setColor(QtGui.QPalette.ToolTipText, QtCore.Qt.black)
            palette.setColor(QtGui.QPalette.Text, QtCore.Qt.black)
            palette.setColor(QtGui.QPalette.Button,
                             QtGui.QColor(240, 240, 240))
            palette.setColor(QtGui.QPalette.ButtonText, QtCore.Qt.black)
            palette.setColor(QtGui.QPalette.BrightText, QtCore.Qt.red)

            palette.setColor(QtGui.QPalette.Highlight,
                             QtGui.QColor(0, 67, 202, 200).lighter())
            palette.setColor(QtGui.QPalette.HighlightedText, QtCore.Qt.black)
            app.setPalette(palette)

    # def check_box_state_change(self):
    #     self.text_holder.append('Animation toggled')
    #     if self.animated_checkbox.checkState()== True:
    #         self.remove_item()
    #     if self.animated_checkbox.checkState()==False and self.plot_type.itemText(3)!='Comparison':
    #         self.add_item()
    # def remove_item(self):
    #     self.plot_type.removeItem(3)
    #     self.plot_type.repaint()
    # def add_item(self):
    #     self.plot_type.insertItem(3,'Comparison')
    # self.plot_type.repaint()

    def start_covid(self):

        with urllib.request.urlopen("https://geolocation-db.com/json") as url:
            data = json.loads(url.read().decode())
            self.country_name.setText(str(data['country_name']))
        self.get_covid()
        self.text_holder.setText(datetime.datetime.now().strftime("%I:%M:%S") +
                                 ' : Country Located : ' +
                                 self.country_name.text())
        self.text_holder.append(datetime.datetime.now().strftime("%I:%M:%S") +
                                ' : Plotting infections')
        self.country_name.setText('None Selected')
class CustomGraph(QGroupBox):
    def __init__(self, title, *args, **kargs):
        super().__init__()
        setConfigOptions(antialias=True)
        self.title = title
        self.graph = PlotWidget(self, title=title, *args, **kargs)
        r = self.geometry()
        self.graph.setGeometry(2, 2, r.width() - 4 - 17, r.height() - 4)
        self.x = []
        self.y = []
        self.range = [-1, 1]
        self.plotdata = None
        self.update_style()
        QApplication.instance().paletteChanged.connect(self.update_style)

    def resizeEvent(self, e):
        super().resizeEvent(e)
        r = self.geometry()
        self.graph.setGeometry(2, 2, r.width() - 4 - 17, r.height() - 4)

    def plot(self):
        rn = self.range
        x = self.x
        y = self.y
        if not self.plotdata:
            self.plotdata = self.graph.plot(x,
                                            y,
                                            pen=mkPen(color=self.hcolor,
                                                      width=2))
        while y[-1] > rn[1]:
            rn[1] *= 2
        while y[-1] < rn[0]:
            rn[0] *= 2
        self.graph.plotItem.setRange(xRange=(0, (x[-1] // 20 + 1) * 20),
                                     yRange=rn,
                                     disableAutoRange=True)
        self.plotdata.setData(x, y)

    def update_style(self, palette=None):
        palette = palette or self.palette()
        bgcolor = palette.color(self.backgroundRole())
        bcolor = palette.color(QPalette.Base)
        fgcolor = palette.color(QPalette.WindowText)
        self.hcolor = palette.color(QPalette.Active, QPalette.Highlight)
        self.graph.setBackground(bgcolor)
        self.setStyleSheet("background-color:{};".format(bgcolor.name()))
        self.graph.plotItem.vb.setBackgroundColor(bcolor)
        self.graph.setTitle(
            "<span style=\"color:{};font-family:Sans-serif;font-size:7pt\">{}</span>"
            .format(fgcolor.name(), self.title))
        l = self.graph.getAxis("left")
        b = self.graph.getAxis("bottom")
        t = self.graph.getAxis("top")
        r = self.graph.getAxis("right")
        self.graph.showAxis('top')
        self.graph.showAxis('right')
        t.style['showValues'] = False
        r.style['showValues'] = False
        small_font = QFont(small_font_family)
        small_font.setPixelSize(small_font_size)
        l.setTickFont(small_font)
        b.setTickFont(small_font)
        pen = mkPen(fgcolor, width=1)
        l.setTextPen(pen)
        b.setTextPen(pen)
        l.setStyle(tickTextOffset=2)
        b.setStyle(tickTextOffset=0)
        l.setZValue(0)
        b.setZValue(0)
        t.setZValue(0)
        r.setZValue(0)
        l.setPen(pen)
        b.setPen(pen)
        t.setPen(pen)
        r.setPen(pen)
        l.style['tickLength'] = 5
        b.style['tickLength'] = 5
        t.style['tickLength'] = 0
        r.style['tickLength'] = 0
        l.setWidth(18)
        if self.plotdata:
            self.plotdata = None
            self.plot()