示例#1
0
    def addSeries(
        self,
        _x2idx: typing.Dict,
        _idx2x: list,
        _chart: QChart,
        _axis_x: QValueAxis,
        _axis_y: QValueAxis,
    ):
        bar_set = QBarSet(self.name)
        tmp_dict = dict(zip(self.x_list, self.y_list))
        for k in _idx2x:
            try:
                bar_set.append(tmp_dict[k])
            except KeyError:
                bar_set.append(0)

        if self.color is not None:
            bar_set.setColor(self.color)

        bar_series = QBarSeries()
        bar_series.append(bar_set)
        _chart.addSeries(bar_series)
        _chart.setAxisX(_axis_x, bar_series)
        _chart.setAxisY(_axis_y, bar_series)

        if self.show_value:
            self.createShow()
示例#2
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Demo12_1, QChart 基本绘图")
        self.resize(580, 420)
        chart = QChart()
        chart.setTitle("简单函数曲线")
        chartView = QChartView(self)
        chartView.setChart(chart)
        self.setCentralWidget(chartView)
        series0 = QLineSeries()
        series1 = QLineSeries()
        series0.setName("sin曲线")
        series1.setName("cos曲线")
        chart.addSeries(series0)
        chart.addSeries(series1)
        t = 0
        intv = 0.1
        pointCount = 100
        for i in range(pointCount):
            y1 = math.cos(t)
            series0.append(t, y1)
            y2 = 1.5 * math.sin(t + 20)
            series1.append(t, y2)
            t = t + intv
        axisX = QValueAxis()
        axisX.setRange(0, 10)
        axisX.setTitleText("time(secs)")
        axisY = QValueAxis()
        axisY.setRange(-2, 2)
        axisY.setTitleText("value")

        chart.setAxisX(axisX, series0)
        chart.setAxisY(axisY, series0)
        chart.setAxisX(axisX, series1)
        chart.setAxisY(axisY, series1)
示例#3
0
    def addSeries(
        self,
        _x2idx: typing.Dict,
        _idx2x: list,
        _chart: QChart,
        _axis_x: QValueAxis,
        _axis_y: QValueAxis,
    ):
        series = QBoxPlotSeries()
        series.setName(self.name)
        if self.color is not None:
            series.setBrush(self.color)

        tmp_dict = dict(zip(self.x_list, self.y_list))
        for k in _idx2x:
            try:
                series.append(QBoxSet(*tmp_dict[k]))
            except KeyError:
                series.append(QBoxSet())

        _chart.addSeries(series)
        _chart.setAxisX(_axis_x, series)
        _chart.setAxisY(_axis_y, series)

        if self.show_value:
            self.createShow()
    def createLineChart(self):
        chart = QChart()
        chart.setTitle("像素分布直方图")
        seriesArray = []

        # for i, data_list in enumerate(self.m_dataTable):
        #     series = QLineSeries()
        #     for value, _ in data_list:
        #         series.append(value)
        #     series.setName("Series " + str(i))
        #     seriesArray.append(series)
        #     chart.addSeries(series)

        axisX = QValueAxis()
        axisY = QValueAxis()
        axisX.setRange(0, 255)
        axisY.setRange(0, 50000)

        chart.setAxisX(axisX)
        chart.setAxisY(axisY)

        # for i in seriesArray:
        #     chart.removeSeries(i)

        return chart
示例#5
0
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(400, 300)
        # 抗锯齿
        self.setRenderHint(QPainter.Antialiasing)

        # 图表
        chart = QChart()
        self.setChart(chart)
        # 设置标题
        chart.setTitle('Simple horizontal barchart example')
        # 开启动画效果
        chart.setAnimationOptions(QChart.SeriesAnimations)
        # 添加Series
        series = self.getSeries()
        chart.addSeries(series)
        # 分类
        categories = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
        # 分类x轴
        axis = QBarCategoryAxis()
        axis.append(categories)
        # 创建默认轴线
        chart.createDefaultAxes()
        # 替换默认y轴
        chart.setAxisY(axis, series)
        # 显示图例
        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)
示例#6
0
    def __init__(self,
                 series: QLineSeries,
                 title: str,
                 xTitle: str,
                 yTitle: str,
                 minimumSize=QSize(400, 400),
                 *args):
        super().__init__(*args)

        chart = QChart()
        chart.setTitle(title)

        axisX = QValueAxis(chart)
        axisX.setTitleText(xTitle)
        chart.setAxisX(axisX)

        axisY = QValueAxis(chart)
        axisY.setTitleText(yTitle)
        chart.setAxisY(axisY)

        chart.legend().show()
        chart.legend().setAlignment(Qt.AlignBottom)

        self.setChart(chart)

        self.set_series(series)

        self.setMinimumSize(minimumSize)
        self.setRenderHint(QPainter.Antialiasing)

        self.pan = Pan(self)
示例#7
0
    def addSeries(
        self,
        _x2idx: typing.Dict,
        _idx2x: list,
        _chart: QChart,
        _axis_x: QValueAxis,
        _axis_y: QValueAxis,
    ):
        series = QCandlestickSeries()
        series.setName(self.name)

        for x, y in zip(self.x_list, self.y_list):
            series.append(QCandlestickSet(*y, _x2idx[x]))
        if self.inc_color is not None:
            series.setIncreasingColor(self.inc_color)
        else:
            series.setIncreasingColor(QColor("#c41919"))
        if self.dec_color is not None:
            series.setDecreasingColor(self.dec_color)
        else:
            series.setDecreasingColor(QColor("#009f9f"))

        _chart.addSeries(series)
        _chart.setAxisX(_axis_x, series)
        _chart.setAxisY(_axis_y, series)

        if self.show_value:
            self.createShow()
示例#8
0
    def createBar(self):
        min_num, max_num = 0, 100
        linked_bag_list = []
        try:
            df = self.linked['Beam Diff'].dropna()
            linked_bag_list = df.values.tolist()
            min_num = int(min(linked_bag_list))
            if min_num > 0:                 # check if greater than 0, set to 0
                min_num = 0
            max_num = int(max(linked_bag_list))

        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        count = [0] * (max_num + 1)        # choose the largest num as length of count
        
        for num in linked_bag_list:
            count[int(num)] += 1            # update every number's count

        max_count = max(count)

        setBar = QBarSet('Beam Difference Occurrence')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        chart.setTheme(QChart.ChartThemeBlueIcy)
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Linked Bins Histogram')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setTitleText("Attenuation Window")
        axisX.setRange(min_num, max_num+20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setTitleText("Frequency")
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().hide()

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        return chartView
示例#9
0
    def load_glycation(self, filename: Optional[str] = None) -> None:
        """
        Load glycation data from a CSV file and display it
        in the corresponding chart view.

        :param str filename: directly load this file
        :return: nothing, sets self.se_glycation
        :rtype: None
        """

        # load and clean glycation data
        if filename is None:
            filename, self.last_path = get_filename(
                self, "open", self.tr("Load glycation data ..."),
                self.last_path, FileTypes(["csv"]))
            if filename is None:
                return

        logging.info(
            self.tr("Loading glycation data in '{}'").format(filename))
        try:
            self.glycation = read_clean_datasets(filename)
        except (OSError, ValueError) as e:
            logging.error(str(e))
            QMessageBox.critical(self, self.tr("Error"), str(e))
            return

        # extract x- and y-values from series
        x_values = [str(i) for i in self.glycation.index]
        y_values = [a.nominal_value for a in self.glycation]

        # assemble the chart
        bar_set = QBarSet("glycation abundance")
        bar_set.append(y_values)
        bar_set.setColor(QColor("#a1dab4"))
        bar_set.hovered.connect(self.update_glycation_label)
        bar_series = QBarSeries()
        bar_series.append(bar_set)

        x_axis = QBarCategoryAxis()
        x_axis.append(x_values)
        x_axis.setTitleText(self.tr("count"))

        y_axis = QValueAxis()
        y_axis.setRange(0, 100)
        y_axis.setTitleText(self.tr("abundance"))
        y_axis.setLabelFormat("%d")

        chart = QChart()
        chart.addSeries(bar_series)
        chart.setAxisX(x_axis, bar_series)
        chart.setAxisY(y_axis, bar_series)
        chart.legend().setVisible(False)
        chart.setBackgroundRoundness(0)
        chart.layout().setContentsMargins(0, 0, 0, 0)
        chart.setMargins(QMargins(5, 5, 5, 5))
        self.cvGlycation.setChart(chart)
示例#10
0
def plot_candlechart(ohlc_data):
    app = ParaMakerApplication([])
    #app.setStyleSheet("background-color:black;")

    series = QCandlestickSeries()
    series.setBodyOutlineVisible(False)
    series.setDecreasingColor(Qt.red)
    series.setIncreasingColor(Qt.green)

    rsi = qc.QLineSeries()  # 5-days average data line
    rsi.append(QPointF(ohlc_data[300].timestamp, ohlc_data[300].closed))
    rsi.append(QPointF(ohlc_data[700].timestamp, ohlc_data[700].closed))
    #rsi.append(QPointF(ohlc_data[150].timestamp, ohlc_data[100].closed))
    tm = []  # stores str type data
    # in a loop,  series and rsi append corresponding data
    for candle in ohlc_data:
        series.append(
            QCandlestickSet(candle.opened, candle.high, candle.low,
                            candle.closed))
        #rsi.append(QPointF(num, m))
        tm.append(str(candle.timestamp))
        #rsi.append(str(candle.timestamp))

    #rsi_values = calculate_rsi(14, ohlc_data)

    chart = QChart()
    chart.setBackgroundVisible(False)
    chart.setPlotAreaBackgroundVisible(False)
    chart.addSeries(series)  # candle
    chart.addSeries(rsi)  # rsi line

    #chart.axisX(rsi).setRange(ohlc_data[0].timestamp, ohlc_data[-1].timestamp)

    chart.createDefaultAxes()

    axisXRSI = QValueAxis()
    axisYRSI = QValueAxis()
    axisXRSI.setRange(ohlc_data[0].timestamp, ohlc_data[-1].timestamp)
    axisYRSI.setRange(ohlc_data[0].closed, ohlc_data[-1].closed)
    axisXRSI.setGridLineVisible(False)
    axisYRSI.setGridLineVisible(False)

    chart.setAxisX(axisXRSI, rsi)
    chart.setAxisY(axisYRSI, rsi)

    chart.legend().hide()

    chart.axisX(series).setCategories(tm)
    #chart.axisX(series).setGridLineVisible(False)
    #chart.axisY(series).setGridLineVisible(False)
    ###chart.axisX(rsi).setVisible(False)

    chartview = QChartView(chart)
    chartview.setRenderHint(QPainter.Antialiasing)
    ui = ParaMakerWindow()
    ui.setCentralWidget(chartview)
    sys.exit(app.exec_())
示例#11
0
    def beforeDelay(self):
        print("in before delay bar")
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_time = []
        try:
            total_stopped_time = self.tm.total_stopped_time
            max_num = max(total_stopped_time)
        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        count = total_stopped_time
        count = [0] * (int(max_num) + 1
                       )  # choose the largest num as length of count

        for num in total_stopped_time:
            count[int(num)] += 1  # update every number's count

        max_count = max(count)
        print(len(total_stopped_time), max_count)
        setBar = QBarSet('stop time')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Histogram (before)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num + 20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count + 20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView
示例#12
0
    def afterDelay(self):
        # print("in after delay bar")
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_after_delay = []
        count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
        try:
            total_stopped_after_delay = self.tm.total_stopped_after_delay
            max_num = max(total_stopped_after_delay)
            count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
                 
            for num in total_stopped_after_delay:
                count[int(num)] += 1            # update every number's count

            max_count = max(count)

        except (AttributeError, ValueError):
            self.statusbar.showMessage('Data not ready')

        setBar = QBarSet('Stop Time Occurrence')
        setBar.append(count)
        brush = QBrush(QColor(0xA6E22E))		# Green
        pen = QPen(QColor(0xA6E22E))			# Green
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Occurrence (after)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num+20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView   
示例#13
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Demo12_1, QChart基本绘图")
        self.resize(580, 420)

        #创建chart和chartView
        chart = QChart()  #创建 Chart
        chart.setTitle("简单函数曲线")

        chartView = QChartView(self)  #创建 ChartView
        chartView.setChart(chart)  #Chart添加到ChartView
        self.setCentralWidget(chartView)

        #创建曲线序列
        series0 = QLineSeries()
        series1 = QLineSeries()
        series0.setName("Sin曲线")
        series1.setName("Cos曲线")
        chart.addSeries(series0)  #序列添加到图表
        chart.addSeries(series1)

        #序列添加数值
        t = 0
        intv = 0.1
        pointCount = 100
        for i in range(pointCount):
            y1 = math.cos(t)
            series0.append(t, y1)
            y2 = 1.5 * math.sin(t + 20)
            series1.append(t, y2)
            t = t + intv

##创建坐标轴
        axisX = QValueAxis()  #X 轴
        axisX.setRange(0, 10)  #设置坐标轴范围
        axisX.setTitleText("time(secs)")  #标题
        ##    axisX.setLabelFormat("%.1f")     #标签格式
        ##    axisX.setTickCount(11)           #主分隔个数
        ##    axisX.setMinorTickCount(4)
        ##    axisX.setGridLineVisible(false)

        axisY = QValueAxis()  #Y 轴
        axisY.setRange(-2, 2)
        axisY.setTitleText("value")
        ##    axisY.setTickCount(5)
        ##    axisY.setMinorTickCount(4)
        ##    axisY.setLabelFormat("%.2f")     #标签格式
        ##    axisY.setGridLineVisible(false)

        #为序列设置坐标轴
        chart.setAxisX(axisX, series0)  #为序列设置坐标轴
        chart.setAxisY(axisY, series0)

        chart.setAxisX(axisX, series1)  #为序列设置坐标轴
        chart.setAxisY(axisY, series1)
class AudioRecPlot(QWidget):

    def __init__(self):
        super().__init__()

        self.m_chart = QChart()

        chart_view = QChartView(self.m_chart)
        chart_view.setMinimumSize(800, 600)

        self.m_series = QLineSeries()
        self.m_chart.addSeries(self.m_series)

        axis_x = QValueAxis()
        axis_x.setRange(0, 2000)
        axis_x.setLabelFormat("%g")
        axis_x.setTitleText("Samples")

        axis_y = QValueAxis()
        axis_y.setRange(-1, 1)
        axis_y.setTitleText("Audio level")

        self.m_chart.setAxisX(axis_x, self.m_series)
        self.m_chart.setAxisY(axis_y, self.m_series)
        self.m_chart.setTitle("Data from the microphone")

        main_layout = QVBoxLayout()
        main_layout.addWidget(chart_view)
        self.setLayout(main_layout)

        format_audio = QAudioFormat()
        format_audio.setSampleRate(48000)
        format_audio.setChannelCount(1)
        format_audio.setSampleSize(8)
        format_audio.setCodec("audio/pcm")
        format_audio.setByteOrder(QAudioFormat.LittleEndian)
        format_audio.setSampleType(QAudioFormat.UnSignedInt)

        input_devices = QAudioDeviceInfo.defaultInputDevice()
        self.m_audio_input = QAudioInput(input_devices, format_audio)

        self.m_device = XYSeriesIODevice(self.m_series)
        self.m_device.open(QIODevice.WriteOnly)

        self.m_audio_input.start(self.m_device)

        self.init_ui()

    def init_ui(self):
        self.show()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.m_audio_input.stop()
        self.m_device.close()
示例#15
0
    def agg_glycoforms(self) -> None:
        """
        Display glycoform data in the corresponding chart view.

        :return: nothing
        :rtype: None
        """

        # aggregate "other" abundances
        if self.cbAggGlycoforms.isChecked():
            agg_abundance = (
                self.glycoforms.iloc[self.sbAggGlycoforms.value():].sum())
            self.glycoforms_agg = (
                self.glycoforms.iloc[:self.sbAggGlycoforms.value()].append(
                    pd.Series(agg_abundance, index=[self.tr("other")])))
        else:
            self.glycoforms_agg = self.glycoforms

        # extract x- and y-values from series
        x_values = [str(i) for i in self.glycoforms_agg.index]
        y_values = [a.nominal_value for a in self.glycoforms_agg]

        # assemble the chart
        bar_set = QBarSet("glycoform abundance")
        bar_set.append(y_values)
        bar_set.setColor(QColor("#2c7fb8"))
        bar_set.hovered.connect(self.update_glycoform_label)
        bar_series = QBarSeries()
        bar_series.append(bar_set)

        x_axis = QBarCategoryAxis()
        x_axis.append(x_values)
        x_axis.setTitleVisible(False)
        x_axis.setLabelsAngle(270)

        range_max = max(self.glycoforms_agg).nominal_value
        range_max = math.ceil(range_max / 20) * 20
        tick_count = range_max // 20 + 1
        y_axis = QValueAxis()
        y_axis.setRange(0, range_max)
        y_axis.setTickCount(tick_count)
        y_axis.setTitleText(self.tr("abundance"))
        y_axis.setLabelFormat("%d")

        chart = QChart()
        chart.addSeries(bar_series)
        chart.setAxisX(x_axis, bar_series)
        chart.setAxisY(y_axis, bar_series)
        chart.legend().setVisible(False)
        chart.setBackgroundRoundness(0)
        chart.layout().setContentsMargins(0, 0, 0, 0)
        chart.setMargins(QMargins(5, 5, 5, 5))
        self.cvGlycoforms.setChart(chart)
示例#16
0
class ChartTab(QChartView):
    def __init__(self):
        QChartView.__init__(self)
        self.chart = QChart()
        self.candleSeries = QCandlestickSeries(self)
        self.candleSeries.setIncreasingColor(Qt.blue)
        self.candleSeries.setBodyOutlineVisible(False)
        self.candleSeries.setDecreasingColor(Qt.red)
        self.candleSeries.setMaximumColumnWidth(20)
        self.candleSeries.clicked.connect(lambda set: print(set.high()))

        self.xAxis = QDateTimeAxis()
        self.xAxis.setTickCount(10)
        self.xAxis.setFormat("h:mm")
        self.yAxis = QValueAxis()

        for candle in data:
            self.addCandle(
                self.get_integer_price(candle[0]),
                self.get_integer_price(candle[1]),
                self.get_integer_price(candle[2]),
                self.get_integer_price(candle[3]),
                datetime.strptime(candle[4], '%Y%m%d%H%M%S').timestamp() *
                1000)

        self.chart.addSeries(self.candleSeries)
        self.setChart(self.chart)
        self.chart.setAxisX(self.xAxis, self.candleSeries)
        self.chart.setAxisY(self.yAxis, self.candleSeries)
        self.chart.legend().setVisible(False)

    def mouseMoveEvent(self, QMouseEvent):
        chartValues = self.chart.mapToValue(QMouseEvent.pos())
        price = chartValues.y()
        print(price)

    def addCandle(self, open, close, high, low, timestamp):
        candlestickSet = QCandlestickSet()
        candlestickSet.setOpen(open)
        candlestickSet.setClose(close)
        candlestickSet.setHigh(high)
        candlestickSet.setLow(low)
        candlestickSet.setTimestamp(timestamp)

        pen = QPen()
        candlestickSet.setPen(pen)
        self.candleSeries.append(candlestickSet)

    def get_integer_price(self, str_price):
        return int(str_price.strip()[1:])
示例#17
0
    def beforeDelayDistribution(self):
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_time = []
        count = [0]
        try:
            total_stopped_time = self.tm.total_stopped_time
            max_num = len(total_stopped_time)							# change from max() to len() 2/12 11:11
            count = total_stopped_time
            max_count = max(count)
        except (AttributeError, ValueError):            
            self.statusbar.showMessage('Data not ready')
        
        setBar = QBarSet('stop time')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Distribution (before)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView  
示例#18
0
    def crearGraficoBarras(self):
        paises = [
            "EEUU", "China", "Japon", "Alemania", "Reino Unido",
            "Resto del mundo"
        ]
        valores = [24.32, 14.85, 8.91, 12.54, 7.85, 31.53]
        colores = [
            Qt.blue, Qt.red, Qt.darkYellow, Qt.gray, Qt.black, Qt.darkCyan
        ]

        grafico = QChart()
        grafico.setMargins(QMargins(30, 30, 30, 30))
        grafico.setTheme(QChart.ChartThemeLight)
        grafico.setTitle("% Distribución del PIB global")
        grafico.setAnimationOptions(QChart.SeriesAnimations)

        for i in range(len(paises)):
            series = QBarSeries()

            barSet = QBarSet(paises[i])
            barSet.setColor(colores[i])
            barSet.setLabelColor(Qt.yellow)
            barSet.append(valores[i])

            series.append(barSet)
            series.setLabelsVisible(True)
            series.setLabelsAngle(-90)
            # series.setLabelsPrecision(2)
            series.setLabelsFormat("@value %")
            series.setLabelsPosition(QAbstractBarSeries.LabelsCenter)

            grafico.addSeries(series)

        axisX = QBarCategoryAxis()
        axisX.append(paises)

        axisY = QValueAxis()
        axisY.setRange(0, 31.53)
        axisY.setTickCount(10)
        axisY.setLabelFormat("%.2f %")

        grafico.createDefaultAxes()
        grafico.setAxisX(axisX, None)
        grafico.setAxisY(axisY, None)

        grafico.legend().setVisible(True)
        grafico.legend().setAlignment(Qt.AlignBottom)

        return grafico
示例#19
0
    def addSeries(self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart,
                  _axis_x: QValueAxis, _axis_y: QValueAxis):
        series = QScatterSeries()
        series.setName(self.name)
        for x, y in zip(self.x_list, self.y_list):
            series.append(_x2idx[x], y)
        if self.color is not None:
            series.setColor(self.color)

        _chart.addSeries(series)
        _chart.setAxisX(_axis_x, series)
        _chart.setAxisY(_axis_y, series)

        if self.show_value:
            self.createShow()
示例#20
0
    def addSeries(
            self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart,
            _axis_x: QValueAxis, _axis_y: QValueAxis
    ):
        series = QLineSeries()
        series.setName(self.name)
        for x, y in zip(self.x_list, self.y_list):
            series.append(_x2idx[x], y)
        if self.color is not None:
            series.setColor(self.color)

        _chart.addSeries(series)
        _chart.setAxisX(_axis_x, series)
        _chart.setAxisY(_axis_y, series)

        if self.show_value:
            self.createShow()
示例#21
0
class QtBarChart(QChartView):
    def __init__(self, spec):
        super().__init__(None)
        self.spec = spec
        self.chart = QChart()
        # self.chart.setTitle(str(self.spec.variables))
        self.chart.legend().hide()
        self.mainset = QBarSet("")
        self.mainset.append([0 for i in range(len(spec.variables))])
        self.mainset.setColor(
            QColor(spec.color[0], spec.color[1], spec.color[2]))
        self.series = QBarSeries()
        self.series.append(self.mainset)

        self.setMinimumWidth(400)
        self.setMinimumHeight(230)

        self.axis_x = QBarCategoryAxis()
        self.axis_y = QValueAxis()
        self.axis_x.append(spec.variables)
        self.chart.addSeries(self.series)
        self.chart.setAxisX(self.axis_x, self.series)
        self.chart.setAxisY(self.axis_y, self.series)

        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)

        self._updates_per_second = 10
        self._dataset = []

    def clear(self):
        self._dataset = []

    def update_data(self, dataset):
        data = []
        for d in dataset:
            data.append(d)
        self._dataset = data

    def redraw(self):
        if len(self._dataset) > 0:
            for i in range(len(self._dataset)):
                self.mainset.replace(i, self._dataset[i])
            self.axis_y.setRange(0, max(self._dataset))
示例#22
0
    def addSeries(
            self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart,
            _axis_x: QValueAxis, _axis_y: QValueAxis
    ):
        bar_set = QBarSet(self.name)
        tmp_dict = dict(zip(self.x_list, self.y_list))
        for k in _idx2x:
            if k in tmp_dict.keys():
                bar_set.append(tmp_dict[k])
            else:
                bar_set.append(0)

        if self.color is not None:
            bar_set.setColor(self.color)

        bar_series = QBarSeries()
        bar_series.append(bar_set)
        _chart.addSeries(bar_series)
        _chart.setAxisX(_axis_x, bar_series)
        _chart.setAxisY(_axis_y, bar_series)

        if self.show_value:
            self.createShow()
示例#23
0
    def addSeries(
            self, _x2idx: typing.Dict, _idx2x: list, _chart: QChart,
            _axis_x: QValueAxis, _axis_y: QValueAxis
    ):
        series = QCandlestickSeries()
        series.setName(self.name)

        for x, y in zip(self.x_list, self.y_list):
            series.append(QCandlestickSet(*y, _x2idx[x]))
        if self.inc_color is not None:
            series.setIncreasingColor(self.inc_color)
        else:
            series.setIncreasingColor(QColor('#c41919'))
        if self.dec_color is not None:
            series.setDecreasingColor(self.dec_color)
        else:
            series.setDecreasingColor(QColor('#009f9f'))

        _chart.addSeries(series)
        _chart.setAxisX(_axis_x, series)
        _chart.setAxisY(_axis_y, series)

        if self.show_value:
            self.createShow()
示例#24
0
class Ui(mainwindow.Ui_MainWindow):
    def __init__(self, MainWindow):
        #super(Ui, self).__init__(M)
        super(Ui, self).setupUi(MainWindow)
        #uic.loadUi('UI/mainwindow.ui', self)

        self.MainWindow = MainWindow

        self.initialize()

    def close(self):
        self.MainWindow.close()

    def style(self):
        return self.MainWindow.style()

    def initialize(self):
        self.tabWidget.setCurrentIndex(0)
        self.actionExit.triggered.connect(self.close)
        self.action_Plot.setEnabled(False)

        self.actionNext.setIcon(
            self.style().standardIcon(
                QtWidgets.QStyle.SP_ArrowForward))
        self.actionPrevious.setIcon(
            self.style().standardIcon(
                QtWidgets.QStyle.SP_ArrowBack))
        self.action_Open.setIcon(
            self.style().standardIcon(
                QtWidgets.QStyle.SP_DialogOpenButton))
        self.actionSave.setIcon(
            self.style().standardIcon(
                QtWidgets.QStyle.SP_DriveFDIcon))

        self.actionSave.triggered.connect(self.save)

        self.action_Open.triggered.connect(self.getOpenFilename)

        self.actionNext.triggered.connect(self.nextPacket)
        self.actionPrevious.triggered.connect(self.previousPacket)
        self.actionAbout.triggered.connect(self.about)

        self.actionPrevious.setEnabled(False)
        self.actionNext.setEnabled(False)
        self.actionSave.setEnabled(False)
        self.action_Plot.setEnabled(False)
        self.actionPaste.triggered.connect(self.onPasteTriggered)
        # self.actionLog.triggered.connect(self.dockWidget_2.show)
        self.actionSet_IDB.triggered.connect(self.onSetIDBClicked)
        self.plotButton.clicked.connect(self.onPlotButtonClicked)
        self.exportButton.clicked.connect(self.onExportButtonClicked)
        self.action_Plot.triggered.connect(self.onPlotActionClicked)
        self.actionLoad_mongodb.triggered.connect(self.onLoadMongoDBTriggered)
        self.mdb=None

        self.current_row = 0
        self.data=[]
        self.x=[]
        self.y=[]
        self.xlabel='x'
        self.ylabel='y'

        self.chart = QChart()
        self.chart.layout().setContentsMargins(0,0,0,0)
        self.chart.setBackgroundRoundness(0)
        self.savePlotButton.clicked.connect(self.savePlot)
        
        self.chartView = QChartView(self.chart)
        self.gridLayout.addWidget(self.chartView, 1, 0, 1, 15)

        # IDB location

        self.settings = QtCore.QSettings('FHNW', 'stix_parser')
    def onExportButtonClicked(self):
        if self.y:
            filename = str(QtWidgets.QFileDialog.getSaveFileName(
                None, "Save file", "", "*.csv")[0])
            if filename:
                with open(filename,'w') as f:
                    f.write('{},{}\n'.format(self.xlabel,self.ylabel))
                    for xx,yy in zip(self.x,self.y):
                        f.write('{},{}\n'.format(xx,yy))
                    self.showMessage('The data has been written to {}'.format(filename))
        else:
            msgBox = QtWidgets.QMessageBox()
            msgBox.setIcon(QtWidgets.QMessageBox.Information)
            msgBox.setText('Plot first!')
            msgBox.setWindowTitle("Warning")
            msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
            msgBox.exec_()


    def savePlot(self):
        #if self.figure.get_axes():
        if self.chart:
            filename = str(QtWidgets.QFileDialog.getSaveFileName(
                None, "Save file", "", "*.png *.jpg")[0])
            if filename:
                if not filename.endswith(('.png','.jpg')):
                    filename+='.png'
                #self.figure.savefig(filename)
                p=self.chartView.grab()
                p.save(filename)
                self.showMessage(('Saved to %s.' % filename))


        else:
            msgBox = QtWidgets.QMessageBox()
            msgBox.setIcon(QtWidgets.QMessageBox.Information)
            msgBox.setText('The canvas is empty!')
            msgBox.setWindowTitle("STIX DATA VIEWER")
            msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
            msgBox.exec_()

    def onPasteTriggered(self):
        pass

    def showMessageBox(self, message, content):
        msg = QtWidgets.QMessageBox()
        msg.setIcon(QtWidgets.QMessageBox.Critical)
        msg.setText("Error")
        msg.setInformativeText(message)
        msg.setWindowTitle("Error")
        msg.setDetailedText(content)
        msg.setStandardButtons(QtWidgets.QMessageBox.Ok |
                               QtWidgets.QMessageBox.Cancel)
        retval = msg.exec_()

    def showMessage(self, msg):
        # if destination != 1:
        self.statusbar.showMessage(msg)
        # if destination !=0 :
        #    self.listWidget_2.addItem(msg)

    def onSetIDBClicked(self):
        pass
    def save(self):
        pass

    def setListViewSelected(self, row):
        #index = self.model.createIndex(row, 0);
        # if index.isValid():
        #    self.model.selectionModel().select( index, QtGui.QItemSelectionModel.Select)
        pass

    def about(self):
        msgBox = QtWidgets.QMessageBox()
        msgBox.setIcon(QtWidgets.QMessageBox.Information)
        msgBox.setText("STIX raw data parser and viewer, [email protected]")
        msgBox.setWindowTitle("Stix data viewer")
        msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
        msgBox.exec_()

    def nextPacket(self):
        self.current_row += 1
        length=len(self.data)
        
        if self.current_row>=length:
            self.current_row=length-1
            self.showMessage('No more packet!')
            

        self.showPacket(self.current_row)
        self.setListViewSelected(self.current_row)

    def previousPacket(self):
        self.current_row -= 1
        if self.current_row <0:
            self.current_row=0
            self.showMessage('Reach the first packet!')

        self.showPacket(self.current_row)
        self.setListViewSelected(self.current_row)

    def getOpenFilename(self):
        pass

    def openFile(self, filename):
        pass



    def onDataLoaded(self, data,clear=True):
        if not clear:
            self.data.append(data)
        else:
            self.data = data
        self.displayPackets(clear)

        if self.data:
            self.actionPrevious.setEnabled(True)
            self.actionNext.setEnabled(True)
            self.actionSave.setEnabled(True)
            self.action_Plot.setEnabled(True)

    def displayPackets(self,clear=True):
        if clear:
            self.packetTreeWidget.clear()
        t0=0
        for p in self.data:
            if type(p) is not dict:
                continue
            header = p['header']
            root = QtWidgets.QTreeWidgetItem(self.packetTreeWidget)
            if t0==0:
                t0=header['time']

            root.setText(0, '{:.2f}'.format(header['time']-t0))
            root.setText(1,
                         ('TM({},{}) - {}').format(header['service_type'],
                                                   header['service_subtype'],
                                                   header['DESCR']))
        self.total_packets = len(self.data)
        self.showMessage((('%d packets loaded') % (self.total_packets)))
        self.packetTreeWidget.currentItemChanged.connect(self.onPacketSelected)
        self.showPacket(0)

    def onLoadMongoDBTriggered(self):
        diag=QtWidgets.QDialog()
        diag_ui=mongo_dialog.Ui_Dialog()
        diag_ui.setupUi(diag)
        diag_ui.pushButton.setFocus(True)
        #self.settings = QtCore.QSettings('FHNW', 'stix_parser')
        self.mongo_server= self.settings.value('mongo_server', [], str)
        self.mongo_port= self.settings.value('mongo_port', [], str)
        self.mongo_user= self.settings.value('mongo_user', [], str)
        self.mongo_pwd= self.settings.value('mongo_pwd', [], str)

        if self.mongo_server:
            diag_ui.serverLineEdit.setText(self.mongo_server)
        if self.mongo_port:
            diag_ui.portLineEdit.setText(self.mongo_port)

        if self.mongo_user:
            diag_ui.userLineEdit.setText(self.mongo_user)
        if self.mongo_pwd:
            diag_ui.pwdLineEdit.setText(self.mongo_pwd)

        diag_ui.pushButton.clicked.connect(partial(self.loadRunsFromMongoDB,diag_ui))
        diag_ui.buttonBox.accepted.connect(partial(self.loadDataFromMongoDB,diag_ui,diag))
        diag.exec_()
    def loadRunsFromMongoDB(self,dui):
        server=dui.serverLineEdit.text()
        port=dui.portLineEdit.text()
        user=dui.userLineEdit.text()
        pwd=dui.pwdLineEdit.text()

        self.showMessage('saving setting...')
        if self.mongo_server!=server:
            self.settings.setValue('mongo_server', server)
        if self.mongo_port!=port:
            self.settings.setValue('mongo_port', port)

        if self.mongo_user!=user:
            self.settings.setValue('mongo_user', user)
        if self.mongo_pwd!=pwd:
            self.settings.setValue('mongo_pwd', pwd)


        self.showMessage('connecting Mongo database ...')
        self.mdb=mgdb.MongoDB(server,int(port),user,pwd)
        dui.treeWidget.clear()
        self.showMessage('Fetching data...')
        for run in self.mdb.get_runs():
            root = QtWidgets.QTreeWidgetItem(dui.treeWidget)
            root.setText(0, str(run['_id']))
            root.setText(1, run['file'])
            root.setText(2, run['date'])
            root.setText(3, str(run['start']))
            root.setText(4, str(run['end']))
        self.showMessage('Runs loaded!')
    def loadDataFromMongoDB(self,dui,diag):
        selected_runs=[]
        for item in dui.treeWidget.selectedItems():
            selected_runs.append(item.text(0))
        if not selected_runs:
            self.showMessage('Run not selected!')
        if selected_runs:
            diag.done(0)
            self.showMessage('Loading data ...!')
            data=self.mdb.get_packets(selected_runs[0])
            if data:
                self.onDataLoaded(data,clear=True)
            else:
                self.showMessage('No packets found!')
        #close

    def onPacketSelected(self, cur, pre):
        self.current_row = self.packetTreeWidget.currentIndex().row()
        self.showMessage((('Packet #%d selected') % self.current_row))
        self.showPacket(self.current_row)

    def showPacket(self, row):
        if not self.data:
            return
        header = self.data[row]['header']
        self.showMessage(
            (('Packet %d / %d  %s ') %
             (row, self.total_packets, header['DESCR'])))

        self.paramTreeWidget.clear()

        header_root = QtWidgets.QTreeWidgetItem(self.paramTreeWidget)
        header_root.setText(0, "Header")
        rows = len(header)
        for key, val in header.items():
            root = QtWidgets.QTreeWidgetItem(header_root)
            root.setText(0, key)
            root.setText(1, str(val))

        params = self.data[row]['parameters']
        param_root = QtWidgets.QTreeWidgetItem(self.paramTreeWidget)
        param_root.setText(0, "Parameters")
        self.showParameterTree(params, param_root)
        self.paramTreeWidget.expandItem(param_root)
        self.paramTreeWidget.expandItem(header_root)

    def showParameterTree(self, params, parent):
        for p in params:
            root = QtWidgets.QTreeWidgetItem(parent)
            if not p:
                continue
            try:
                param_name=p['name']
                desc=''
                scos_desc=''
                try:
                    desc=param_desc.PCF[param_name]
                    scos_desc=param_desc.SW[param_name]
                except KeyError:
                    pass
                root.setToolTip(1,scos_desc)
                root.setText(0, param_name)
                root.setText(1, desc)
                root.setText(2, str(p['raw']))
                root.setText(3, str(p['value']))
                if 'child' in p:
                    if p['child']:
                        self.showParameterTree(p['child'], root)
            except KeyError:
                self.showMessage(
                    ('[Error  ]: keyError occurred when adding parameter'))
        self.paramTreeWidget.itemDoubleClicked.connect(self.onTreeItemClicked)

    def walk(self, name, params, header, ret_x, ret_y, xaxis=0, data_type=0):
        if not params:
            return
        timestamp = header['time']
        #parameters=[p for p in params if p['name'] == name] 
        for p in params:
            if type(p) is not dict:
                continue
        #for p in parameters:
            if name == p['name']:
                values = None
                #print('data type:{}'.format(data_type))
                if data_type == 0:
                    values = p['raw']
                else:
                    values = p['value']
                try:
                    yvalue = None
                    if (type(values) is tuple) or (type(values) is list):
                        yvalue = float(values[0])
                    else:
                        yvalue = float(values)
                    ret_y.append(yvalue)
                    if xaxis == 1:
                        ret_x.append(timestamp)
                    else:
                        self.showMessage((('Can not plot %s  ') % str(yvalue)))
                except Exception as e:
                    self.showMessage((('%s ') % str(e)))

            if 'child' in p:
                if p['child']:
                    self.walk(
                        name,
                        p['child'],
                        header,
                        ret_x,
                        ret_y,
                        xaxis,
                        data_type)

    def onPlotButtonClicked(self):
        if self.chart:
            self.chart.removeAllSeries()
        if not self.data:
            return
        self.showMessage('Preparing plot ...')
        name = self.paramNameEdit.text()
        packet_selection = self.comboBox.currentIndex()
        xaxis_type = self.xaxisComboBox.currentIndex()
        data_type = self.dataTypeComboBox.currentIndex()

        timestamp = []
        self.y = []
        packet_id = self.current_row
        params = self.data[packet_id]['parameters']
        header = self.data[packet_id]['header']
        current_spid=header['SPID']
        if packet_selection == 0:
            self.walk(
                name,
                params,
                header,
                timestamp,
                self.y,
                xaxis_type,
                data_type)
        elif packet_selection == 1:
            for packet in self.data:
                header = packet['header']
                if packet['header']['SPID'] != current_spid:
                    continue
                #only look for parameters in the packets of the same type
                params = packet['parameters']
                self.walk(
                    name,
                    params,
                    header,
                    timestamp,
                    self.y,
                    xaxis_type,
                    data_type)

        self.x = []



        if not self.y:
            self.showMessage('No data points')
        elif self.y:
            style = self.styleEdit.text()
            if not style:
                style = '-'
            title = '%s' % str(name)
            desc = self.descLabel.text()
            if desc:
                title += '- %s' % desc

            self.chart.setTitle(title)

            ylabel = 'Raw value'
            xlabel = name
            if data_type == 1:
                ylabel = 'Engineering  value'
            if xaxis_type == 0:
                xlabel = "Packet #"
                self.x = range(0, len(self.y))
            if xaxis_type == 1:
                self.x = [t - timestamp[0] for t in timestamp]
                xlabel = 'Time -T0 (s)'

            #if xaxis_type != 2:
            if True:
                series = QLineSeries()
                series2 = None

                # print(y)
                # print(x)
                for xx, yy in zip(self.x, self.y):
                    series.append(xx, yy)

                if 'o' in style:
                    series2 = QScatterSeries()
                    for xx, yy in zip(self.x, self.y):
                        series2.append(xx, yy)
                    self.chart.addSeries(series2)
                self.chart.addSeries(series)

                self.showMessage('plotted!')

                #self.chart.createDefaultAxes()
                axisX = QValueAxis()
                axisX.setTitleText(xlabel)
                axisY = QValueAxis()
                axisY.setTitleText(ylabel)

                self.chart.setAxisX(axisX)
                self.chart.setAxisY(axisY)
                series.attachAxis(axisX)
                series.attachAxis(axisY)

                # histogram
            #else:
            #    nbins = len(set(self.y))
            #    ycounts, xedges = np.histogram(self.y, bins=nbins)
            #    series = QLineSeries()
            #    for i in range(0, nbins):
            #        meanx = (xedges[i] + xedges[i + 1]) / 2.
            #        series.append(meanx, ycounts[i])
            #    # series.append(dataset)
            #    self.chart.addSeries(series)
            #    #self.chart.createDefaultAxes()
            #    self.showMessage('Histogram plotted!')

            #    axisX = QValueAxis()

            #    axisX.setTitleText(name)
            #    axisY = QValueAxis()

            #    axisY.setTitleText("Counts")

            #    self.chart.setAxisY(axisY)
            #    self.chart.setAxisX(axisX)
            ##    series.attachAxis(axisX)
            #    series.attachAxis(axisY)

            # self.widget.setChart(self.chart)
            self.xlabel=xlabel
            self.ylabel=ylabel
            self.chartView.setRubberBand(QChartView.RectangleRubberBand)
            self.chartView.setRenderHint(QtGui.QPainter.Antialiasing)

    def plotParameter(self, name=None, desc=None):
        self.tabWidget.setCurrentIndex(1)
        if name:
            self.paramNameEdit.setText(name)
        if desc:
            self.descLabel.setText(desc)

    def onPlotActionClicked(self):
        self.tabWidget.setCurrentIndex(1)
        self.plotParameter()

    def onTreeItemClicked(self, it, col):
        #print(it, col, it.text(0))
        self.plotParameter(it.text(0), it.text(1))

    def error(self, msg, description=''):
        self.showMessage((('Error: %s - %s') % (msg, description)))

    def warning(self, msg, description=''):
        self.showMessage((('Warning: %s - %s') % (msg, description)))

    def info(self, msg, description=''):
        self.showMessage((('Info: %s - %s') % (msg, description)))
示例#25
0
文件: panes.py 项目: martinohanlon/mu
class PlotterPane(QChartView):
    """
    This plotter widget makes viewing sensor data easy!

    This widget represents a chart that will look for tuple data from
    the MicroPython REPL, Python 3 REPL or Python 3 code runner and will
    auto-generate a graph.
    """

    data_flood = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        # Holds the raw input to be checked for actionable data to display.
        self.input_buffer = []
        # Holds the raw actionable data detected while plotting.
        self.raw_data = []
        self.setObjectName('plotterpane')
        self.max_x = 100  # Maximum value along x axis
        self.max_y = 1000  # Maximum value +/- along y axis
        self.flooded = False  # Flag to indicate if data flooding is happening.

        # Holds deques for each slot of incoming data (assumes 1 to start with)
        self.data = [deque([0] * self.max_x), ]
        # Holds line series for each slot of incoming data (assumes 1 to start
        # with).
        self.series = [QLineSeries(), ]

        # Ranges used for the Y axis (up to 1000, after which we just double
        # the range).
        self.y_ranges = [1, 5, 10, 25, 50, 100, 250, 500, 1000]

        # Set up the chart with sensible defaults.
        self.chart = QChart()
        self.chart.legend().hide()
        self.chart.addSeries(self.series[0])
        self.axis_x = QValueAxis()
        self.axis_y = QValueAxis()
        self.axis_x.setRange(0, self.max_x)
        self.axis_y.setRange(-self.max_y, self.max_y)
        self.axis_x.setLabelFormat("time")
        self.axis_y.setLabelFormat("%d")
        self.chart.setAxisX(self.axis_x, self.series[0])
        self.chart.setAxisY(self.axis_y, self.series[0])
        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)

    def process_bytes(self, data):
        """
        Takes raw bytes and, if a valid tuple is detected, adds the data to
        the plotter.

        The the length of the bytes data > 1024 then a data_flood signal is
        emitted to ensure Mu can take action to remain responsive.
        """
        # Data flooding guards.
        if self.flooded:
            return
        if len(data) > 1024:
            self.flooded = True
            self.data_flood.emit()
            return
        data = data.replace(b'\r\n', b'\n')
        self.input_buffer.append(data)
        # Check if the data contains a Python tuple, containing numbers, on a
        # single line (i.e. ends with \n).
        input_bytes = b''.join(self.input_buffer)
        lines = input_bytes.split(b'\n')
        for line in lines:
            if line.startswith(b'(') and line.endswith(b')'):
                # Candidate tuple. Extract the raw bytes into a numeric tuple.
                raw_values = [val.strip() for val in line[1:-1].split(b',')]
                numeric_values = []
                for raw in raw_values:
                    try:
                        numeric_values.append(int(raw))
                        # It worked, so move onto the next value.
                        continue
                    except ValueError:
                        # Try again as a float.
                        pass
                    try:
                        numeric_values.append(float(raw))
                    except ValueError:
                        # Not an int or float, so ignore this value.
                        continue
                if numeric_values:
                    # There were numeric values in the tuple, so use them!
                    self.add_data(tuple(numeric_values))
        # Reset the input buffer.
        self.input_buffer = []
        if lines[-1]:
            # Append any bytes that are not yet at the end of a line, for
            # processing next time we read data from self.serial.
            self.input_buffer.append(lines[-1])

    def add_data(self, values):
        """
        Given a tuple of values, ensures there are the required number of line
        series, add the data to the line series, update the range of the chart
        so the chart displays nicely.
        """
        # Store incoming data to dump as CSV at the end of the session.
        self.raw_data.append(values)
        # Check the number of incoming values.
        if len(values) != len(self.series):
            # Adjust the number of line series.
            value_len = len(values)
            series_len = len(self.series)
            if value_len > series_len:
                # Add new line series.
                for i in range(value_len - series_len):
                    new_series = QLineSeries()
                    self.chart.addSeries(new_series)
                    self.chart.setAxisX(self.axis_x, new_series)
                    self.chart.setAxisY(self.axis_y, new_series)
                    self.series.append(new_series)
                    self.data.append(deque([0] * self.max_x))
            else:
                # Remove old line series.
                for old_series in self.series[value_len:]:
                    self.chart.removeSeries(old_series)
                self.series = self.series[:value_len]
                self.data = self.data[:value_len]

        # Add the incoming values to the data to be displayed, and compute
        # max range.
        max_ranges = []
        for i, value in enumerate(values):
            self.data[i].appendleft(value)
            max_ranges.append(max([max(self.data[i]), abs(min(self.data[i]))]))
            if len(self.data[i]) > self.max_x:
                self.data[i].pop()

        # Re-scale y-axis.
        max_y_range = max(max_ranges)
        y_range = bisect.bisect_left(self.y_ranges, max_y_range)
        if y_range < len(self.y_ranges):
            self.max_y = self.y_ranges[y_range]
        elif max_y_range > self.max_y:
            self.max_y += self.max_y
        elif max_y_range < self.max_y / 2:
            self.max_y = self.max_y / 2
        self.axis_y.setRange(-self.max_y, self.max_y)

        # Ensure floats are used to label y axis if the range is small.
        if self.max_y <= 5:
            self.axis_y.setLabelFormat("%2.2f")
        else:
            self.axis_y.setLabelFormat("%d")

        # Update the line series with the data.
        for i, line_series in enumerate(self.series):
            line_series.clear()
            xy_vals = []
            for j in range(self.max_x):
                val = self.data[i][self.max_x - 1 - j]
                xy_vals.append((j, val))
            for point in xy_vals:
                line_series.append(*point)

    def set_theme(self, theme):
        """
        Sets the theme / look for the plotter pane.
        """
        if theme == 'day':
            self.chart.setTheme(QChart.ChartThemeLight)
        elif theme == 'night':
            self.chart.setTheme(QChart.ChartThemeDark)
        else:
            self.chart.setTheme(QChart.ChartThemeHighContrast)
示例#26
0
class QtHistogram(QChartView):
    def __init__(self, spec):
        super().__init__(None)
        self.spec = spec
        self.chart = QChart()
        self.chart.setTitle(self.spec.variable)
        self.chart.legend().hide()

        self.mainset = QBarSet("")
        self.mainset.append([0] * len(spec.bins))
        self.mainset.setColor(
            QColor(spec.color[0], spec.color[1], spec.color[2]))
        self.series = QBarSeries()
        self.series.append(self.mainset)

        self.setMinimumWidth(400)
        self.setMinimumHeight(230)

        self.y_ranges = [0, 1, 5, 10, 25, 50, 100, 250, 500, 1000]
        self.max_y = 1000
        self.max_y_range = 1000
        self.lookback = 30
        self.recent_max_y = deque([self.max_y_range] * self.lookback)

        font = QtGui.QFont()
        font.setPixelSize(10)

        self.axis_x = QBarCategoryAxis()
        self.axis_x.setLabelsAngle(-90)
        self.axis_x.setLabelsFont(font)

        self.axis_y = QValueAxis()
        self.axis_y.setRange(0, self.max_y)
        self.axis_x.append(map(str, spec.bins))
        self.chart.addSeries(self.series)
        self.chart.setAxisX(self.axis_x, self.series)
        self.chart.setAxisY(self.axis_y, self.series)

        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)

        self._updates_per_second = 10
        self._dataset = []

    def clear(self):
        self._dataset = []

    def update_data(self, dataset):
        data = []
        for d in dataset:
            data.append(d)
        self._dataset = data

    def redraw(self):
        if len(self._dataset) > 0:
            for i in range(len(self._dataset)):
                self.mainset.replace(i, self._dataset[i])

            # Calculate max of current values
            max_y_range = max(self._dataset)

            # Store max value
            self.recent_max_y.appendleft(max_y_range)
            if len(self.recent_max_y) > self.lookback:
                self.recent_max_y.pop()

            # Set max based on the last 30 max values,
            # to avoid flickering
            self.max_y_range = max(self.recent_max_y)

            y_range = bisect.bisect_left(self.y_ranges, self.max_y_range)
            if y_range < len(self.y_ranges):
                self.max_y = self.y_ranges[y_range]
            elif max_y_range > self.max_y:
                self.max_y += self.max_y
            elif max_y_range < self.max_y / 2:
                self.max_y = self.max_y / 2

            self.axis_y.setRange(0, self.max_y)
示例#27
0
    def agg_results(self) -> None:
        """
        Display results in the corresponding chart view.

        :return: nothing
        :rtype: None
        """

        # aggregate "other" abundances
        if self.cbAggResults.isChecked():
            agg_abundance = (
                self.results.iloc[self.sbAggResults.value():].sum())
            agg_abundance["glycoform"] = self.tr("other")
            self.results_agg = (
                self.results.iloc[:self.sbAggResults.value()].append(
                    agg_abundance, ignore_index=True))
        else:
            self.results_agg = self.results

        # extract x- and y-values from series
        x_values = list(self.results_agg["glycoform"].str.split(" or").str[0])
        y_values_obs = list(self.results_agg["abundance"])
        y_values_cor = list(self.results_agg["corr_abundance"])

        # assemble the chart
        bar_set_obs = QBarSet(self.tr("observed"))
        bar_set_obs.append(y_values_obs)
        bar_set_obs.setColor(QColor("#225ea8"))
        bar_set_obs.hovered.connect(self.update_results_label)
        bar_set_cor = QBarSet(self.tr("corrected"))
        bar_set_cor.append(y_values_cor)
        bar_set_cor.setColor(QColor("#41b6c4"))
        bar_set_cor.hovered.connect(self.update_results_label)
        bar_series = QBarSeries()
        bar_series.append([bar_set_obs, bar_set_cor])

        x_axis = QBarCategoryAxis()
        x_axis.append(x_values)
        x_axis.setTitleVisible(False)
        x_axis.setLabelsAngle(270)

        range_min = min(
            self.results_agg[["abundance", "corr_abundance"]].min().min(), 0)
        range_min = math.floor(range_min / 20) * 20
        range_max = (self.results_agg[["abundance",
                                       "corr_abundance"]].max().max())
        range_max = math.ceil(range_max / 20) * 20
        tick_count = (range_max - range_min) // 20 + 1
        y_axis = QValueAxis()
        y_axis.setRange(range_min, range_max)
        y_axis.setTickCount(tick_count)
        y_axis.setTitleText(self.tr("abundance"))
        y_axis.setLabelFormat("%d")

        chart = QChart()
        chart.addSeries(bar_series)
        chart.setAxisX(x_axis, bar_series)
        chart.setAxisY(y_axis, bar_series)
        chart.legend().setVisible(False)
        chart.setBackgroundRoundness(0)
        chart.layout().setContentsMargins(0, 0, 0, 0)
        chart.setMargins(QMargins(5, 5, 5, 5))
        self.cvResults.setChart(chart)
class MainInterface(QMainWindow):
    '''实现 GUI 以及其连接整个程序的功能

    @属性说明: 


    @方法说明: 


    @注意: 

    '''
    def __init__(self, parent=None):
        super().__init__(parent)  # 父类初始化
        self.ui = Ui_main_interface()  # 创建UI类
        self.ui.setupUi(self)
        self.showMaximized()  # 最大化界面
        self.setWindowTitle("疲劳检测")  # 界面标题
        self.time = QTimer()  # 创建定时器
        self._connect_slot()  # 初始化槽函数连接
        self.eye_data_chart_init()  # 初始化眼睛闭合数据折线图
        self._t = 0  # 用来计数
        self._perclos_threshold = 0.3  # 设置初始化阈值

    def _connect_slot(self):
        '''初始化信号与槽的连接

        @参数说明: 
            无

        @返回值: 
            无

        @注意: 
            无
        '''
        self.ui.btn_start.clicked.connect(self._display)
        self.time.timeout.connect(self.test)

    def paintEvent(self, evevt):
        """绘图软件背景图

        Qt里面默认事件处理函数,在界面需要重新绘制时触发
        此方法主要是绘制软件的背景图

        @参数说明: 
            evevt:Qt默认事件

        @返回值: 
            无

        @注意: 
            无
        """
        temp_painter = QPainter(self)
        # 创建背景图QPixmap()对象
        soft_background_image = QPixmap("resources/groud.jpg")
        # 绘制背景图
        temp_painter.drawPixmap(0, 0, self.width(), self.height(),
                                soft_background_image)
        # 执行父类的paintEvent()函数,以便父类执行其内建的一些操作
        super().paintEvent(evevt)

    def eye_data_chart_init(self):
        '''初始化左右眼闭合程度曲线图表

        @参数说明: 
            无

        @返回值: 
            无

        @注意: 
            无
        '''
        # 创建 chart 和 chartview
        self._chart = QChart()
        self._chart.setTitle("眼睛闭合程度值")  # 设置图表标题
        self._chartView = QChartView(self)
        self._chartView.setChart(self._chart)  # chart 添加到 chartview

        # 完成布局
        self.ui.horizontalLayout_2.addWidget(self._chartView)

        ## 创建曲线系列
        self._series0 = QLineSeries()
        self._series1 = QLineSeries()
        self._series0.setName("左眼曲线")  # 设置曲线名
        self._series1.setName("右眼曲线")
        self._chart.addSeries(self._series0)  # 序列添加到图表
        self._chart.addSeries(self._series1)

        # 创建坐标轴
        self._axis_x = QValueAxis()  # x 轴
        self._axis_x.setRange(0, 60)  # 设置 x 轴坐标范围
        self._axis_x.setTitleText("time(secs)")  # x 轴标题
        self._axis_y = QValueAxis()  # y 轴
        self._axis_y.setRange(0, 0.5)  # 设置 y 轴坐标范围
        self._axis_y.setTitleText("value")  # y 轴标题

        # 为序列设置坐标轴
        self._chart.setAxisX(self._axis_x, self._series0)
        self._chart.setAxisY(self._axis_y, self._series0)
        self._chart.setAxisX(self._axis_x, self._series1)
        self._chart.setAxisY(self._axis_y, self._series1)

    @pyqtSlot(bool)
    def _display(self, checked):
        '''

        @参数说明: 


        @返回值: 


        @注意: 

        '''
        if (checked == False):  # 当按键为 False 时,停止检查
            self.ui.le_eye_threshold.setEnabled(True)
            self.ui.btn_start.setText("启动")
            self.ui.lb_fatigue_detection.setText("检测停止")
            self.time.stop()
        else:
            threshold_str = self.ui.le_eye_threshold.text()  # 获得睁闭眼阈值
            threshold_str = re.match(r"\d\.\d\d$", threshold_str)  # 对睁闭眼阈值做限定
            if (threshold_str == None):
                message_title = "阈值格式错误"
                message_text = "请输入正确的阈值格式,格式为 x.xx (x 为数字)"
                QMessageBox.critical(self, message_title, message_text)
            else:
                self.ui.btn_start.setText("停止")
                self.ui.le_eye_threshold.setEnabled(False)
                model_path = r"E:\make_data\facial"  # 人脸关键模型路径
                opencv_facial_path = r"E:\Fatigue_Detection\model_data\facial_model\haarcascade_frontalface_default.xml"  # 人脸检测模型路径
                cap_index = eval(
                    self.ui.cmb_cap_index.currentText())  # 从 combabox 获取设想头索引
                # cap_file = r"C:\Users\LWL\Pictures\Camera Roll\WIN_20200503_07_51_19_Pro.mp4"
                self.facial_data = GetFacialData(
                    tf_model=model_path,
                    facial_model_file=opencv_facial_path,
                    cap_index=cap_index)  # 创建 GetFacialData 类
                self.time.start(1000)  # 设置每次检测的间隔时间
                self.ui.lb_fatigue_detection.setText("检测中")
                self._series0.clear()
                self._series1.clear()
                self._t = 0  # 重新开始计数
                self._perclos_threshold = eval(threshold_str.group())

    def test(self):
        ret, frame = self.facial_data.get_frame()
        if (ret == -1):
            message_title = "摄像头打开失败"
            message_text = "摄像头打开失败,请检测摄像头索引是否正确"
            self.time.stop()
            QMessageBox.critical(self, message_title, message_text)
        if (ret == -2):
            message_title = "获取帧失败"
            message_text = "从摄像头获取帧失败,请重启软件"
            self.time.stop()
            QMessageBox.critical(self, message_title, message_text)
        else:
            frame = cv2.medianBlur(frame, 5)
            ret, rect = self.facial_data.get_facial(frame)
            h, w = frame.shape[:2]
            if (ret == -1):
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                temp_q_image = QImage(frame, w, h, QImage.Format_RGB888)
                #  在 lb_display 中显示图片
                self.ui.lb_display.setPixmap(QPixmap.fromImage(temp_q_image))
                self.ui.lb_facial_number.setText(str(rect))  # 显示当前检测人脸数
            else:
                self.ui.lb_facial_number.setText("1")  # 显示当前检测人脸数
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                facial = frame[rect[2]:rect[3], rect[0]:rect[1]]

                image = cv2.cvtColor(facial, cv2.COLOR_RGB2GRAY)
                image_h, image_w = image.shape[:2]
                image = cv2.resize(image, (150, 150))
                image = np.reshape(image, [1, 150, 150, 1])
                image = image / 255.
                facial_keypoints = self.facial_data.get_result(image)
                facial_keypoints = (facial_keypoints[0] + 1) / 2
                facial_keypoints[::
                                 2] = facial_keypoints[::2] * image_w + rect[0]
                facial_keypoints[
                    1::2] = facial_keypoints[1::2] * image_h + rect[2]

                # 圈出人脸范围
                facial = cv2.rectangle(frame, (rect[0], rect[2]),
                                       (rect[1], rect[3]), (255, 0, 0), 1)

                # 将人脸多特征点标记到图片上
                for i in range(12):
                    facial = cv2.circle(frame,
                                        (int(facial_keypoints[2 * i]),
                                         int(facial_keypoints[2 * i + 1])), 2,
                                        (255, 0, 0), -1)  # 进行打点

                # 获得左右眼的闭合程度
                eye_process_data = result_process.eyes_process(
                    facial_keypoints)

                # 添加点到图表上
                self._series0.append(self._t, eye_process_data[0])
                self._series1.append(self._t, eye_process_data[1])

                # 在label上显示左右眼计算值
                self.ui.lb_left_eye_figure.setText(str(
                    eye_process_data[0]))  # 显示左眼的计算值
                self.ui.lb_right_eye_figure.setText(str(
                    eye_process_data[1]))  # 显示右眼的计算值

                temp_q_image = QImage(facial.data, w, h, QImage.Format_RGB888)
                #  在 lb_display 中显示图片
                self.ui.lb_display.setPixmap(QPixmap.fromImage(temp_q_image))

                self._t += 1  # 每个 1s 绘制点
                if (self._t > 60):
                    # 获取 series0 以及 series1 中所有的数据
                    left_eye_point = self._series0.pointsVector()
                    right_eye_point = self._series1.pointsVector()
                    # 使用正则表达式提取其中的计算数据
                    left_eye_data = np.array(
                        re.findall(r"\d+\.\d{2,5}", str(left_eye_point)))
                    right_eye_data = np.array(
                        re.findall(r"\d+\.\d{2,5}", str(right_eye_point)))
                    perclos_judge_result = result_process.perclos_judge(
                        left_eye_data, self._perclos_threshold)
                    # 对 perclos_judge 的结果进行输出
                    if (perclos_judge_result == -2):
                        self.ui.lb_fatigue_detection.setText("过度疲劳")
                        message_title = "过度疲劳警告提醒"
                        message_text = "为了你的人身安全,请停下手中工作,休息一段时间!"
                        QMessageBox.critical(self, message_title,
                                             message_text)  # 过度疲劳提醒
                    elif (perclos_judge_result == -1):
                        self.ui.lb_fatigue_detection.setText("疲劳状态")
                    else:
                        self.ui.lb_fatigue_detection.setText("状态良好")
                    # 清除所有的 series0 以及 series1 数据,重新绘图
                    self._series0.clear()
                    self._series1.clear()
                    self._t = 0  # 重新开始计数
示例#29
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    Main application window
    """
    WIDTH = 150
    HEIGHT = 50
    MARGIN = 5
    max_ping = 0
    max_loss = 0

    def __init__(self, host, history, history_size, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.host = host
        self.history = history
        self.history_size = history_size
        self.setupUi(self)
        self.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.position_to_dock()
        self.series_delay = QLineSeries()
        self.series_loss = QLineSeries()
        self.axis_X = QDateTimeAxis()  # pylint: disable=invalid-name
        self.axis_X.setTickCount(3)
        self.axis_X.setFormat("HH:mm")
        self.axis_X.setTitleText("Time")
        self.chart = QChart()
        self.chart.addSeries(self.series_delay)
        self.chart.addSeries(self.series_loss)
        self.chart.setTitle(f"Connection to {self.host}")
        self.init_series(self.series_delay, "Delay ms")
        self.init_series(self.series_loss, "Loss %")
        self.chart.legend().setVisible(False)
        self.chart.legend().setAlignment(Qt.AlignBottom)
        self.chart.layout().setContentsMargins(0, 0, 0, 0)
        self.chart.setBackgroundRoundness(0)
        self.chart.setMargins(QMargins(0, 0, 0, 0))
        self.chartWidget.setChart(self.chart)
        self.chartWidget.setRenderHint(QPainter.Antialiasing)

    def init_series(self, series, label):
        """
        Series settings
        """
        self.chart.setAxisX(self.axis_X, series)
        axis_Y = QValueAxis()  # pylint: disable=invalid-name
        axis_Y.setLabelFormat("%i")
        axis_Y.setTitleText(label)
        axis_Y.setRange(0, 100)
        self.chart.addAxis(axis_Y, Qt.AlignLeft)
        self.chart.setAxisY(axis_Y, series)

    def add_series(self, ping, loss):
        """
        Append series data
        """
        self.max_ping = max(ping or 0, self.max_ping)
        self.max_loss = max(loss, self.max_loss)
        if self.series_delay.count() > self.history_size:
            self.series_delay.remove(0)
        self.series_delay.append(
            QDateTime.currentDateTime().toMSecsSinceEpoch(), ping or 0)
        if self.series_loss.count() > self.history_size:
            self.series_loss.remove(0)
        self.series_loss.append(
            QDateTime.currentDateTime().toMSecsSinceEpoch(), loss)
        self.axis_X.setRange(
            QDateTime.currentDateTime().addSecs(-self.history),
            QDateTime.currentDateTime())
        self.chart.axisY().setRange(0, self.max_ping + self.MARGIN)

    def position_to_dock(self):
        """
        Adjust main window position according to it's size and desktop
        """
        desktop_geometry = QDesktopWidget().availableGeometry()
        self.setGeometry(
            desktop_geometry.width() - self.width() - self.MARGIN,
            desktop_geometry.height() - self.height() - self.MARGIN,
            self.width(), self.height())

    def set_labels(self, mean_=None, curr=None, loss=None):
        """
        Update window text
        """
        mean_text = curr_text = loss_text = "No connection"
        if mean_ is not None:
            mean_text = f"Mean ping: {mean_}ms"
        if curr is not None:
            curr_text = f"Last ping: {curr}ms"
        if loss is not None:
            loss_text = f"Ping loss: {loss}%"
        self.meanLabel.setText(mean_text)
        self.currLabel.setText(curr_text)
        self.lossLabel.setText(loss_text)

    def toggle(self, reason):
        """
        Toggle window visibility
        """
        if reason == QSystemTrayIcon.ActivationReason.DoubleClick:  # pylint: disable=no-member
            self.setVisible(not self.isVisible())
            if self.isVisible():
                self.activateWindow()
示例#30
0
class barChartView(QChartView):
    def __init__(self, xAxis=[], *args, **kwargs):
        super(barChartView, self).__init__(*args, **kwargs)
        self.initChart(xAxis)

        # line 宽度需要调整
        self.lineItem = QGraphicsLineItem(self._chart)
        pen = QPen(Qt.gray)
        self.lineItem.setPen(pen)
        self.lineItem.setZValue(998)
        self.lineItem.hide()
        self.cal()

    # 一些固定计算,减少mouseMoveEvent中的计算量
    def cal(self):
        # 提示widget
        self.toolTipWidget = GraphicsProxyWidget(self._chart)
        # 获取x和y轴的最小最大值
        axisX, axisY = self._chart.axisX(), self._chart.axisY()
        self.category_len = len(axisX.categories())
        self.min_x, self.max_x = -0.5, self.category_len - 0.5
        self.min_y, self.max_y = axisY.min(), axisY.max()
        # 坐标系中左上角顶点
        self.point_top = self._chart.mapToPosition(
            QPointF(self.min_x, self.max_y))

    def setCat(self, data):
        self.categories = data

    #初始化
    def initChart(self, xAxis):
        self._chart = QChart()
        # 调整边距
        self._chart.layout().setContentsMargins(0, 0, 0, 0)  # 外界
        self._chart.setMargins(QMargins(3, 0, 3, 0))  # 内界
        self._chart.setBackgroundRoundness(0)
        self._chart.setBackgroundVisible(False)
        # 设置主题
        self._chart.setTheme(QChart.ChartThemeBlueIcy)
        # 抗锯齿
        self.setRenderHint(QPainter.Antialiasing)
        # 开启动画效果
        self._chart.setAnimationOptions(QChart.SeriesAnimations)
        self.categories = xAxis
        self._series = QBarSeries(self._chart)
        self._chart.addSeries(self._series)
        self._chart.createDefaultAxes()  # 创建默认的轴
        self._axis_x = QBarCategoryAxis(self._chart)
        self._axis_x.append(self.categories)
        self._axis_y = QValueAxis(self._chart)
        self._axis_y.setTitleText("任务数")
        self._axis_y.setRange(0, 10)
        self._chart.setAxisX(self._axis_x, self._series)
        self._chart.setAxisY(self._axis_y, self._series)
        # chart的图例
        legend = self._chart.legend()
        legend.setVisible(True)

        self.setChart(self._chart)

    def mouseMoveEvent(self, event):
        super(barChartView, self).mouseMoveEvent(event)
        pos = event.pos()
        # 把鼠标位置所在点转换为对应的xy值
        x = self._chart.mapToValue(pos).x()
        y = self._chart.mapToValue(pos).y()
        index = round(x)
        # 得到在坐标系中的所有bar的类型和点
        serie = self._chart.series()[0]
        bars = [
            (bar, bar.at(index)) for bar in serie.barSets()
            if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y
        ]
        # print(bars)
        if bars:
            right_top = self._chart.mapToPosition(
                QPointF(self.max_x, self.max_y))
            # 等分距离比例
            step_x = round(
                (right_top.x() - self.point_top.x()) / self.category_len)
            posx = self._chart.mapToPosition(QPointF(x, self.min_y))
            self.lineItem.setLine(posx.x(), self.point_top.y(), posx.x(),
                                  posx.y())
            self.lineItem.show()
            try:
                title = self.categories[index]
            except:
                title = ""
            t_width = self.toolTipWidget.width()
            t_height = self.toolTipWidget.height()
            # 如果鼠标位置离右侧的距离小于tip宽度
            x = pos.x() - t_width if self.width() - \
                pos.x() - 20 < t_width else pos.x()
            # 如果鼠标位置离底部的高度小于tip高度
            y = pos.y() - t_height if self.height() - \
                pos.y() - 20 < t_height else pos.y()
            self.toolTipWidget.show(title, bars, QPoint(x, y))
        else:
            self.toolTipWidget.hide()
            self.lineItem.hide()
示例#31
0
def main():
    import sys
    from PyQt5.QtChart import QChart, QChartView
    from PyQt5.QtCore import Qt
    from PyQt5.QtGui import QPainter
    from PyQt5.QtWidgets import QApplication, QMainWindow

    import numpy as np

    @pyqtSlot(QPointF, bool)
    def help(point, state):
        print('help')

    app = QApplication(sys.argv)

    size = 50
    bdr = 2
    opc = 0.3
    special = False

    markers = [
        XMarkerCircle(),
        XMarkerPlus(),
        XMarkerDash(),
        XMarkerSquare(),
        XMarkerDiamond(),
        XMarkerCross(),
        XMarkerTriangle()
    ]

    # Chart Setup
    chart = QChart()
    chart.axisX = QValueAxis()
    chart.axisY = QValueAxis()
    chart.axisX.setTickCount(11)
    chart.axisY.setTickCount(11)

    chart.legend().setVisible(True)
    chart.legend().setAlignment(Qt.AlignBottom)
    chartView = QChartView(chart)
    chartView.setRenderHint(QPainter.Antialiasing)

    class scatser(QScatterSeries):
        def __init__(self, parent=None):
            super(scatser, self).__init__(parent)
            self.hovered.connect(self.onHovered)
            self.pen = QPen(Qt.black)

        @pyqtSlot(QPointF, bool)
        def onHovered(self, point, state):
            if state:
                spoint = self.chart().mapToPosition(point) - QPointF(
                    0, size / 2)
                self.ttip = XToolTipLabel('Hello from:\n x: %.1f, y: %.1f' %
                                          (point.x(), point.y()),
                                          colour=self.color())

                self.ttip_proxy = chart.scene().addWidget(self.ttip)
                w = self.ttip.width()
                h = self.ttip.height()
                self.ttip_proxy.setPos(spoint.x() - w / 2.0, spoint.y() - h)
                self.ttip.updateGeometry()
            else:
                self.ttip_proxy.deleteLater()

    mcount = 0
    nm = len(markers)
    pos = [0.1, 0.3, 0.5, 0.7, 0.9]
    for i in pos:
        for j in pos:
            if mcount == nm:
                mcount = 0
            #print(mcount)
            m = markers[mcount]
            m.setBrush(size, size, border=bdr, opacity=opc)
            ser = scatser()

            ser.append(i, j)

            if special:
                ser.setBorderColor(QColor(1, 1, 1, 1))
                ser.setMarkerSize(size)
                #ser.setMarkerShape(1)
                ser.setBrush(m)

            else:
                xtypemarker(ser, size=size, width=bdr, fillalpha=50)
            chart.addSeries(ser)
            chart.setAxisX(chart.axisX, ser)
            chart.setAxisY(chart.axisY, ser)
            mcount += 1

    chart.axisX.setMin(0)
    chart.axisY.setMin(0)
    chart.axisX.setMax(1)
    chart.axisY.setMax(1)
    window = QMainWindow()
    window.setCentralWidget(chartView)
    window.resize(800, 800)
    window.show()

    sys.exit(app.exec_())
class Interface(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(Interface, self).__init__()
        self.__dataGenerator = None
        self.__wid = QWidget(self)
        self.setCentralWidget(self.__wid)
        self.__layout = QGridLayout()
        self.__layout.setSpacing(5)
        self.__axisx = QValueAxis()
        self.__axisx.setRange(0.0, 100.0)
        self.__axisy = QValueAxis()
        self.__values = list()
        self.__counter = 0
        self.__data_iterator = None
        self.time_ms = 0
        self.timer = QTimer(self)
        self.timerInterval = 1000
        self.timer.setInterval(self.timerInterval)
        self.timer.timeout.connect(self.run_simulation)
        self.initUI()

    def init_values(self):
        self.__counter = 0
        self.__data_iterator = self.__dataGenerator.get_values(100)
        self.time_ms = 0

    def on_tick(self):
        try:
            values = next(self.__data_iterator)
            self.__values.append(values)
        except StopIteration:
            self.timer.stop()

        self.__writeLog()
        self.__drawParetoChart()
        self.__drawComparisonChart()

    def __setWindowProperties(self, parent):
        self.setWindowTitle("Title")
        self.setGeometry(100, 60, 1000, 600)

    def __createOptimisationChartGroupBox(self):
        groupBox = QGroupBox("Множество Парето")
        layout = QGridLayout()
        layout.setSpacing(0)

        self.__pareto_chart = QChart()
        self.__pareto_chart_series = []
        view = QChartView(self.__pareto_chart)
        layout.addWidget(view)
        groupBox.setLayout(layout)
        return groupBox

    def __createButtonsGroupBox(self):
        groupBox = QGroupBox("Кнопки")
        layout = QGridLayout()
        layout.setSpacing(5)
        self.__btn_start = QPushButton("Запуск", self)
        self.__btn_stop = QPushButton("Остановка", self)
        layout.addWidget(self.__btn_start, 1, 1, 1, 3)
        layout.addWidget(self.__btn_stop, 1, 4, 1, 3)
        groupBox.setLayout(layout)
        return groupBox

    def __createQueryParametersGroupBox(self):
        groupBox = QGroupBox("Параметры запросов")
        layout = QGridLayout()
        layout.setSpacing(5)
        label_query_count = QLabel("Количество запросов: ")
        self.spinbox_query_count = QSpinBox()
        self.spinbox_query_count.setRange(100, 1000)
        self.spinbox_query_count.setSingleStep(100)
        label_update_frequency = QLabel("Частота обновления (мсек): ")
        self.spinbox_update_frequency = QSpinBox()
        self.spinbox_update_frequency.setRange(100, 300)
        self.spinbox_update_frequency.setSingleStep(100)
        layout.addWidget(label_query_count, 1, 1, 1, 1)
        layout.addWidget(self.spinbox_query_count, 1, 2, 1, 3)
        layout.addWidget(label_update_frequency, 2, 1, 1, 1)
        layout.addWidget(self.spinbox_update_frequency, 2, 2, 1, 3)
        groupBox.setLayout(layout)
        return groupBox

    def __createLogGroupBox(self):
        groupBox = QGroupBox("Замеры времени")
        self.__plainTextEdit_time_logs = QPlainTextEdit("")
        vbox = QVBoxLayout()
        vbox.addWidget(self.__plainTextEdit_time_logs)
        vbox.addStretch(1)
        groupBox.setLayout(vbox)
        return groupBox

    def __createComparisonChartGroupBox(self):
        groupBox = QGroupBox("Сравнительный график")
        layout = QGridLayout()
        layout.setSpacing(0)
        self.__comparison_chart = QChart()
        self.__comparison_chart_series = []
        self.__comparison_view = QChartView(self.__comparison_chart)
        layout.addWidget(self.__comparison_view)
        groupBox.setLayout(layout)
        return groupBox

    def __start_btn_clicked(self):
        self.__drawParetoChart()
        self.interval = int(self.spinbox_query_count.value())
        self.timerInterval = int(self.spinbox_update_frequency.value())
        self.__dataGenerator = DataGenerator(self.timerInterval * 10)
        self.init_values()
        self.timer.start(self.timerInterval)

    def run_simulation(self):
        self.time_ms += self.timerInterval
        self.on_tick()

    def __stop_btn_clicked(self):
        self.timer.stop()

    def __drawParetoChart(self):
        def make_noise(value, noise_size):
            return value + (noise_size / -2 + noise_size * random.random())

        self.__pareto_chart.removeAllSeries()

        series1 = QScatterSeries()
        series1.setMarkerShape(QScatterSeries.MarkerShapeCircle)
        series1.setMarkerSize(5)
        series1.append(make_noise(23, 2), make_noise(25, 2))
        series1.setBrush(QColor(Qt.red))
        self.__pareto_chart.addSeries(series1)
        self.__axisy.setRange(0.0, 100.0)

        series3 = QScatterSeries()
        series3.setName("Точка утопии")
        series3.setMarkerShape(QScatterSeries.MarkerShapeCircle)
        series3.setMarkerSize(10)
        series3.append(make_noise(2, 0.5), make_noise(23, 2))
        self.__pareto_chart.addSeries(series3)

        series2 = QScatterSeries()
        series2.setName("Оптимальный")
        series2.setMarkerShape(QScatterSeries.MarkerShapeCircle)
        series2.setMarkerSize(7)
        series2.append(make_noise(2, 0.5), make_noise(45, 4))
        self.__pareto_chart.addSeries(series2)

        self.__pareto_chart.setAxisX(self.__axisx, series1)
        self.__pareto_chart.setAxisY(self.__axisy, series1)
        self.__pareto_chart.setAxisX(self.__axisx, series2)
        self.__pareto_chart.setAxisY(self.__axisy, series2)
        self.__pareto_chart.setAxisX(self.__axisx, series3)
        self.__pareto_chart.setAxisY(self.__axisy, series3)

    def __writeLog(self):
        self.__counter += 1
        self.__plainTextEdit_time_logs.moveCursor(QTextCursor.End)
        time_string = ("[%d:%d]" %
                       (self.time_ms / 1000, self.time_ms % 1000 / 100))
        try:
            optimal = self.__values[-1][2] - self.__values[-2][2]
            other = self.__values[-1][1] - self.__values[-2][1]
        except IndexError:
            optimal = 0
            other = 0
        for i in range(self.__counter):
            self.__plainTextEdit_time_logs.insertPlainText(
                '{0} {1:20} {2:1.4} \n'.format(time_string, 'Оптимальный:',
                                               float(optimal)))
            self.__plainTextEdit_time_logs.insertPlainText(
                '{0} {1:20} {2:1.4} \n'.format(time_string, 'Другой:',
                                               float(other)))
        self.__plainTextEdit_time_logs.moveCursor(QTextCursor.End)

    def __drawComparisonChart(self):
        self.__comparison_chart.removeAllSeries()
        series1 = QLineSeries(self)
        series2 = QLineSeries(self)
        series1.setName("Оптимальный")
        series2.setName("Другой")
        [(series1.append(i[0], i[1]), series2.append(i[0], i[2]))
         for i in self.__values]
        self.__comparison_chart.addSeries(series1)
        self.__comparison_chart.addSeries(series2)

        self.__comparison_chart.createDefaultAxes()

    def initUI(self):
        self.__layout.addWidget(self.__createOptimisationChartGroupBox(), 1, 1,
                                8, 5)
        self.__layout.addWidget(self.__createLogGroupBox(), 9, 1, 2, 5)
        self.__layout.addWidget(self.__createButtonsGroupBox(), 1, 6, 1, 5)
        self.__layout.addWidget(self.__createQueryParametersGroupBox(), 2, 6,
                                2, 5)
        self.__layout.addWidget(self.__createComparisonChartGroupBox(), 4, 6,
                                7, 5)
        self.__wid.setLayout(self.__layout)
        self.__btn_start.clicked.connect(self.__start_btn_clicked)
        self.__btn_stop.clicked.connect(self.__stop_btn_clicked)
        self.__setWindowProperties(self)
        self.show()

    def closeEvent(self, event):  # событие закрытия окна
        reply = QMessageBox.question(self, 'Выход',
                                     "Вы уверены, что хотите выйти?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def showWarning(self, message):
        q = QMessageBox()
        q.setIcon(QMessageBox.Warning)
        q.setText(message)
        q.setWindowTitle("Ошибка")
        q.setStandardButtons(QMessageBox.Ok)
        q.exec_()
示例#33
0
class PlotterPane(QChartView):
    """
    This plotter widget makes viewing sensor data easy!

    This widget represents a chart that will look for tuple data from
    the MicroPython REPL, Python 3 REPL or Python 3 code runner and will
    auto-generate a graph.
    """

    data_flood = pyqtSignal()

    def __init__(self, theme='day', parent=None):
        super().__init__(parent)
        # Holds the raw input to be checked for actionable data to display.
        self.input_buffer = []
        # Holds the raw actionable data detected while plotting.
        self.raw_data = []
        self.setObjectName('plotterpane')
        self.max_x = 100  # Maximum value along x axis
        self.max_y = 1000  # Maximum value +/- along y axis
        self.flooded = False  # Flag to indicate if data flooding is happening.

        # Holds deques for each slot of incoming data (assumes 1 to start with)
        self.data = [
            deque([0] * self.max_x),
        ]
        # Holds line series for each slot of incoming data (assumes 1 to start
        # with).
        self.series = [
            QLineSeries(),
        ]

        # Ranges used for the Y axis (up to 1000, after which we just double
        # the range).
        self.y_ranges = [1, 5, 10, 25, 50, 100, 250, 500, 1000]

        # Set up the chart with sensible defaults.
        self.chart = QChart()
        self.chart.legend().hide()
        self.chart.addSeries(self.series[0])
        self.axis_x = QValueAxis()
        self.axis_y = QValueAxis()
        self.axis_x.setRange(0, self.max_x)
        self.axis_y.setRange(-self.max_y, self.max_y)
        self.axis_x.setLabelFormat("time")
        self.axis_y.setLabelFormat("%d")
        self.chart.setAxisX(self.axis_x, self.series[0])
        self.chart.setAxisY(self.axis_y, self.series[0])
        self.setChart(self.chart)
        self.setRenderHint(QPainter.Antialiasing)

    def process_bytes(self, data):
        """
        Takes raw bytes and, if a valid tuple is detected, adds the data to
        the plotter.

        The the length of the bytes data > 1024 then a data_flood signal is
        emitted to ensure Mu can take action to remain responsive.
        """
        # Data flooding guards.
        if self.flooded:
            return
        if len(data) > 1024:
            self.flooded = True
            self.data_flood.emit()
            return
        data = data.replace(b'\r\n', b'\n')
        self.input_buffer.append(data)
        # Check if the data contains a Python tuple, containing numbers, on a
        # single line (i.e. ends with \n).
        input_bytes = b''.join(self.input_buffer)
        lines = input_bytes.split(b'\n')
        for line in lines:
            if line.startswith(b'(') and line.endswith(b')'):
                # Candidate tuple. Extract the raw bytes into a numeric tuple.
                raw_values = [val.strip() for val in line[1:-1].split(b',')]
                numeric_values = []
                for raw in raw_values:
                    try:
                        numeric_values.append(int(raw))
                        # It worked, so move onto the next value.
                        continue
                    except ValueError:
                        # Try again as a float.
                        pass
                    try:
                        numeric_values.append(float(raw))
                    except ValueError:
                        # Not an int or float, so ignore this value.
                        continue
                if numeric_values:
                    # There were numeric values in the tuple, so use them!
                    self.add_data(tuple(numeric_values))
        # Reset the input buffer.
        self.input_buffer = []
        if lines[-1]:
            # Append any bytes that are not yet at the end of a line, for
            # processing next time we read data from self.serial.
            self.input_buffer.append(lines[-1])

    def add_data(self, values):
        """
        Given a tuple of values, ensures there are the required number of line
        series, add the data to the line series, update the range of the chart
        so the chart displays nicely.
        """
        # Store incoming data to dump as CSV at the end of the session.
        self.raw_data.append(values)
        # Check the number of incoming values.
        if len(values) != len(self.series):
            # Adjust the number of line series.
            value_len = len(values)
            series_len = len(self.series)
            if value_len > series_len:
                # Add new line series.
                for i in range(value_len - series_len):
                    new_series = QLineSeries()
                    self.chart.addSeries(new_series)
                    self.chart.setAxisX(self.axis_x, new_series)
                    self.chart.setAxisY(self.axis_y, new_series)
                    self.series.append(new_series)
                    self.data.append(deque([0] * self.max_x))
            else:
                # Remove old line series.
                for old_series in self.series[value_len:]:
                    self.chart.removeSeries(old_series)
                self.series = self.series[:value_len]
                self.data = self.data[:value_len]

        # Add the incoming values to the data to be displayed, and compute
        # max range.
        max_ranges = []
        for i, value in enumerate(values):
            self.data[i].appendleft(value)
            max_ranges.append(max([max(self.data[i]), abs(min(self.data[i]))]))
            if len(self.data[i]) > self.max_x:
                self.data[i].pop()

        # Re-scale y-axis.
        max_y_range = max(max_ranges)
        y_range = bisect.bisect_left(self.y_ranges, max_y_range)
        if y_range < len(self.y_ranges):
            self.max_y = self.y_ranges[y_range]
        elif max_y_range > self.max_y:
            self.max_y += self.max_y
        elif max_y_range < self.max_y / 2:
            self.max_y = self.max_y / 2
        self.axis_y.setRange(-self.max_y, self.max_y)

        # Ensure floats are used to label y axis if the range is small.
        if self.max_y <= 5:
            self.axis_y.setLabelFormat("%2.2f")
        else:
            self.axis_y.setLabelFormat("%d")

        # Update the line series with the data.
        for i, line_series in enumerate(self.series):
            line_series.clear()
            xy_vals = []
            for j in range(self.max_x):
                val = self.data[i][self.max_x - 1 - j]
                xy_vals.append((j, val))
            for point in xy_vals:
                line_series.append(*point)

    def set_theme(self, theme):
        """
        Sets the theme / look for the plotter pane.
        """
        if theme == 'day':
            self.chart.setTheme(QChart.ChartThemeLight)
        elif theme == 'night':
            self.chart.setTheme(QChart.ChartThemeDark)
        else:
            self.chart.setTheme(QChart.ChartThemeHighContrast)
示例#34
0
class Chart(QWidget):
    def __init__(self, ch0Name='ch0', ch1Name='ch1', ch2Name='ch2', ch3Name='ch3'):
        super(Chart, self).__init__()
        self.ch0Name = ch0Name
        self.ch1Name = ch1Name
        self.ch2Name = ch2Name
        self.ch3Name = ch3Name
        self.data = []
        self.initUI()

    def initUI(self):
        vbox = QVBoxLayout()
        vbox.addWidget(self.chartUI())
        vbox.addWidget(self.controlUI())

        self.setLayout(vbox)

    def chartUI(self):
        self.chart1 = QLineSeries()
        self.chart1.setName(self.ch0Name)
        self.chart1.setPen(QPen(Qt.red))
        self.chart2 = QLineSeries()
        self.chart2.setName(self.ch1Name)
        self.chart2.setPen(QPen(Qt.darkYellow))
        self.chart3 = QLineSeries()
        self.chart3.setName(self.ch2Name)
        self.chart3.setPen(QPen(Qt.green))
        self.chart4 = QLineSeries()
        self.chart4.setName(self.ch3Name)
        self.chart4.setPen(QPen(Qt.blue))

        self.chart = QChart()
        self.chart.addSeries(self.chart1)
        self.chart.addSeries(self.chart2)
        self.chart.addSeries(self.chart3)
        self.chart.addSeries(self.chart4)
        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.chart.setTitle("laser data")

        self.axis_x = QValueAxis()
        self.axis_y = QValueAxis()
        self.axis_x.setTickCount(10)
        self.axis_y.setTickCount(10)
        self.axis_x.setLabelFormat('%d')
        self.axis_y.setLabelFormat('%d')

        self.axis_x.setRange(0, 1000)
        self.axis_y.setRange(100, 300)
        self.chart.setAxisX(self.axis_x, self.chart1)
        self.chart.setAxisY(self.axis_y, self.chart1)
        self.chart.setAxisX(self.axis_x, self.chart2)
        self.chart.setAxisY(self.axis_y, self.chart2)
        self.chart.setAxisX(self.axis_x, self.chart3)
        self.chart.setAxisY(self.axis_y, self.chart3)
        self.chart.setAxisX(self.axis_x, self.chart4)
        self.chart.setAxisY(self.axis_y, self.chart4)

        self.chartView = QChartView()
        self.chartView.setChart(self.chart)
        self.chartView.setRubberBand(QChartView.RectangleRubberBand)
        self.chartView.setRenderHint(QPainter.Antialiasing)

        return self.chartView

    def controlUI(self):
        self.autoRefreshCb = QCheckBox('自动刷新')
        self.autoRefreshCb.setChecked(True)
        self.ch0Enable = QCheckBox(self.ch0Name)
        self.ch1Enable = QCheckBox(self.ch1Name)
        self.ch2Enable = QCheckBox(self.ch2Name)
        self.ch3Enable = QCheckBox(self.ch3Name)
        self.ch0Enable.setChecked(True)
        self.ch1Enable.setChecked(True)
        self.ch2Enable.setChecked(True)
        self.ch3Enable.setChecked(True)
        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.autoRefreshCb)
        hbox1.addWidget(self.ch0Enable)
        hbox1.addWidget(self.ch1Enable)
        hbox1.addWidget(self.ch2Enable)
        hbox1.addWidget(self.ch3Enable)

        self.xDataMinLabel = QLabel('x min:')
        self.xDataMaxLabel = QLabel('x max:')
        self.yDataMinLabel = QLabel('y min:')
        self.yDataMaxLabel = QLabel('y max:')

        self.xDataMinLine = QLineEdit()
        self.xDataMaxLine = QLineEdit()
        self.yDataMinLine = QLineEdit()
        self.yDataMaxLine = QLineEdit()
        self.setBtn = QPushButton('设置')

        hbox = QHBoxLayout()
        hbox.addWidget(self.xDataMinLabel)
        hbox.addWidget(self.xDataMinLine)
        hbox.addWidget(self.xDataMaxLabel)
        hbox.addWidget(self.xDataMaxLine)
        hbox.addWidget(self.yDataMinLabel)
        hbox.addWidget(self.yDataMinLine)
        hbox.addWidget(self.yDataMaxLabel)
        hbox.addWidget(self.yDataMaxLine)
        hbox.addWidget(self.setBtn)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(hbox1)
        mainLayout.addLayout(hbox)
        frame = QFrame()
        frame.setLayout(mainLayout)

        self.setBtn.clicked.connect(self.setAxisRange)
        self.ch0Enable.clicked.connect(self.changeCh)
        self.ch1Enable.clicked.connect(self.changeCh)
        self.ch2Enable.clicked.connect(self.changeCh)
        self.ch3Enable.clicked.connect(self.changeCh)
        return frame

    # @timethis
    def update(self):
        x0Data, y0Data, x1Data, y1Data, x2Data, y2Data, x3Data, y3Data = self.data
        self.chart1.clear()
        self.chart2.clear()
        self.chart3.clear()
        self.chart4.clear()
        try:
            for i in range(0, len(x0Data)):
                if self.ch0Enable.isChecked():
                    self.chart1.append(QPoint(x0Data[i], y0Data[i]))
            for i in range(0, len(x1Data)):
                if self.ch1Enable.isChecked():
                    self.chart2.append(QPoint(x1Data[i], y1Data[i]))
            for i in range(0, len(x2Data)):
                if self.ch2Enable.isChecked():
                    self.chart3.append(QPoint(x2Data[i], y2Data[i]))
            for i in range(0, len(x3Data)):
                if self.ch3Enable.isChecked():
                    self.chart4.append(QPoint(x3Data[i], y3Data[i]))
        except:
            logging.debug('y0Data is %s' % y0Data)
            logging.debug('y1Data is %s' % y1Data)
            logging.debug('y2Data is %s' % y2Data)
            logging.debug('y3Data is %s' % y3Data)
            self.chart1.clear()
            self.chart2.clear()
            self.chart3.clear()
            self.chart4.clear()
        # self.chartView.update()

        if self.autoRefreshCb.isChecked():
            self.fillAxisRange()
            self.setAxisRange()

    def fillAxisRange(self):
        x0Data, y0Data, x1Data, y1Data, x2Data, y2Data, x3Data, y3Data = self.data
        tmp = [min(x0Data), min(x1Data), min(x2Data), min(x3Data)]
        xDataMin = min(tmp)
        tmp = [max(x0Data), max(x1Data), max(x2Data), max(x3Data)]
        xDataMax = max(tmp)
        tmp = [min(y0Data), min(y1Data), min(y2Data), min(y3Data)]
        yDataMin = min(tmp)
        tmp = [max(y0Data), max(y1Data), max(y2Data), max(y3Data)]
        yDataMax = max(tmp)

        xDataAvr = (xDataMin + xDataMax) // 2
        yDataAvr = (yDataMin + yDataMax) // 2

        self.xDataMinLine.setText(str(xDataAvr - xDataAvr*6//5))
        self.xDataMaxLine.setText(str(xDataAvr + xDataAvr*6//5))
        self.yDataMinLine.setText(str(yDataAvr - yDataAvr*6//5))
        self.yDataMaxLine.setText(str(yDataAvr + yDataAvr*6//5))

    @pyqtSlot()
    def setAxisRange(self):
        if self.xDataMinLine.text() and self.xDataMaxLine.text() and \
            self.yDataMinLine.text() and self.yDataMaxLine.text():
            self.axis_x.setRange(int(self.xDataMinLine.text()), int(self.xDataMaxLine.text()))
            self.axis_y.setRange(int(self.yDataMinLine.text()), int(self.yDataMaxLine.text()))
        else:
            QMessageBox.warning(self, '警告', '缺少参数')

    @pyqtSlot()
    def changeCh(self):

        self.chart1.clear()
        self.chart2.clear()
        self.chart3.clear()
        self.chart4.clear()
        x0Data, y0Data, x1Data, y1Data, x2Data, y2Data, x3Data, y3Data = self.data

        for i in range(0, len(x0Data)):
            if self.ch0Enable.isChecked():
                self.chart1.append(QPoint(x0Data[i], y0Data[i]))
        for i in range(0, len(x1Data)):
            if self.ch1Enable.isChecked():
                self.chart2.append(QPoint(x1Data[i], y1Data[i]))
        for i in range(0, len(x2Data)):
            if self.ch2Enable.isChecked():
                self.chart3.append(QPoint(x2Data[i], y2Data[i]))
        for i in range(0, len(x3Data)):
            if self.ch3Enable.isChecked():
                self.chart4.append(QPoint(x3Data[i], y3Data[i]))