Exemple #1
0
class BaseTimedGraph(QChartView):
    def __init__(self, chart=None, parent=None):
        super(BaseTimedGraph, self).__init__(parent)
        self.setObjectName('BaseGraph')

        self.seriesPurgedT = None
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.chart = chart if chart else QChart()

        self.setRenderHint(QPainter.Antialiasing)

        self.axisX = QDateTimeAxis()
        self.axisX.setTickCount(5)
        self.axisX.setFormat('hh:mm:ss')
        self.axisX.setTitleText('Time')
        self.chart.addAxis(self.axisX, Qt.AlignBottom)

        self.axisY = QValueAxis()
        self.axisY.setLabelFormat('%i')
        self.axisY.setMin(0)
        self.axisY.setMax(1024)

        self.chart.addAxis(self.axisY, Qt.AlignLeft)

    def removeOldSeries(self, series, before: int):
        for point in series.pointsVector():
            if point.x() < before:
                series.remove(point)

    async def onBwStats(self, stats):
        pass
 def __init__(self, parent):
     super(ScoresWindow, self).__init__(parent)
     self.parent = parent
     mainLayout = QBoxLayout(QBoxLayout.TopToBottom)
     columnLayout = QBoxLayout(QBoxLayout.LeftToRight)
     column = [QBoxLayout(QBoxLayout.TopToBottom) for i in range(3)]
     for i in column: columnLayout.addLayout(i)
     self.cell = [QLabel() for i in range(9)]
     for i in range(9): column[i//3].addWidget(self.cell[i])
     chartView = QChartView()
     axisY = QValueAxis()
     axisY.setRange(-700,700)
     axisY.setLabelFormat("%d")
     self.chart = LineChart(((10,20,30,40,50,60,70,80),(0,-10,-20,-30,-40,50,-20,0)))
     self.chart.addAxis(axisY, Qt.AlignLeft)
     for i in self.chart.series:
         i.attachAxis(axisY)
     chartView.setChart(self.chart)
     self.level = QLabel()
     mainLayout.addLayout(columnLayout)
     mainLayout.addWidget(chartView)
     self.setLayout(mainLayout)
     self.setFixedSize(300,400)
     self.setModal(True)
     self.setStrings()
 def setAxisRange(self, min, max):
     axisY = QValueAxis()
     axisY.setRange(min, max)
     axisY.setLabelFormat(" ")
     self.addAxis(axisY, Qt.AlignLeft)
     for s in self.series:
         s.attachAxis(axisY)
Exemple #4
0
    def set_x_aix(self, years: []) -> QValueAxis:  # x轴坐标——年份
        x_aix = QValueAxis()
        x_aix.setRange(years[0], years[-1])
        x_aix.setLabelFormat('%d')
        x_aix.setGridLineVisible(True)
        x_aix.setTickCount(len(years))
        x_aix.setMinorTickCount(5)  # 每两个月一个小分级

        return x_aix
Exemple #5
0
   def __createChart(self):
      self.__chart = QChart()
      self.__chart.setTitle("简单函数曲线")
      self.ui.chartView.setChart(self.__chart)
      self.ui.chartView.setRenderHint(QPainter.Antialiasing)

      series0 =  QLineSeries()
      series0.setName("Sin曲线")
      series1 =  QLineSeries()
      series1.setName("Cos曲线")
      self.__curSeries=series0   #当前序列

      pen=QPen(Qt.red)
      pen.setStyle(Qt.DotLine)   #SolidLine, DashLine, DotLine, DashDotLine
      pen.setWidth(2)
      series0.setPen(pen)        #序列的线条设置

      pen.setStyle(Qt.SolidLine) #SolidLine, DashLine, DotLine, DashDotLine
      pen.setColor(Qt.blue)
      series1.setPen(pen)        #序列的线条设置

      self.__chart.addSeries(series0)
      self.__chart.addSeries(series1)

      axisX = QValueAxis()
      self.__curAxis=axisX       #当前坐标轴
      axisX.setRange(0, 10)      #设置坐标轴范围
      axisX.setLabelFormat("%.1f")  #标签格式
      axisX.setTickCount(11)        #主分隔个数
      axisX.setMinorTickCount(4)
      axisX.setTitleText("time(secs)")  #标题
      axisX.setGridLineVisible(True)
      axisX.setMinorGridLineVisible(False)

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

   ##      self.__chart.setAxisX(axisX, series0) #添加X坐标轴
   ##      self.__chart.setAxisX(axisX, series1) #添加X坐标轴
   ##      self.__chart.setAxisY(axisY, series0) #添加Y坐标轴
   ##      self.__chart.setAxisY(axisY, series1) #添加Y坐标轴

   ##另一种实现设置坐标轴的方法
      self.__chart.addAxis(axisX,Qt.AlignBottom) #坐标轴添加到图表,并指定方向
      self.__chart.addAxis(axisY,Qt.AlignLeft)

      series0.attachAxis(axisX)  #序列 series0 附加坐标轴
      series0.attachAxis(axisY)

      series1.attachAxis(axisX)  #序列 series1 附加坐标轴
      series1.attachAxis(axisY)
Exemple #6
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)
Exemple #7
0
 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)
Exemple #8
0
    def update_axes(self):

        # Get and remove all axes
        for axis in self.chart.axes():
            self.chart.removeAxis(axis)

        # Create new axes
        # Create axis X
        # axisX = QDateTimeAxis()
        # axisX.setTickCount(5)
        # axisX.setFormat("dd MMM yyyy")
        # axisX.setTitleText("Date")
        # self.chart.addAxis(axisX, Qt.AlignBottom)
        # axisX.rangeChanged.connect(self.axis_range_changed)

        axisX = QValueAxis()
        axisX.setTickCount(10)
        axisX.setLabelFormat("%li")
        axisX.setTitleText("Seconds")
        self.chart.addAxis(axisX, Qt.AlignBottom)
        # axisX.rangeChanged.connect(self.axis_range_changed)


        # Create axis Y
        axisY = QValueAxis()
        axisY.setTickCount(5)
        axisY.setLabelFormat("%.3f")
        axisY.setTitleText("Values")
        self.chart.addAxis(axisY, Qt.AlignLeft)
        # axisY.rangeChanged.connect(self.axis_range_changed)

        ymin = None
        ymax = None

        # Attach axes to series, find min-max
        for series in self.chart.series():
            series.attachAxis(axisX)
            series.attachAxis(axisY)
            vect = series.pointsVector()
            for i in range(len(vect)):
                if ymin is None:
                    ymin = vect[i].y()
                    ymax = vect[i].y()
                else:
                    ymin = min(ymin, vect[i].y())
                    ymax = max(ymax, vect[i].y())

        # Update range
        # print('min max', ymin, ymax)
        if ymin is not None:
            axisY.setRange(ymin, ymax)

        # Make the X,Y axis more readable
        axisX.applyNiceNumbers()
Exemple #9
0
class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQtChart Demo")
        self.setGeometry(500, 275, 650, 500)

        self.show()
        self.createLineChart()

    def createLineChart(self):
        self.font = QFont("Arial")
        self.font.setPixelSize(16)
        self.font.setBold(True)

        self.pen = QPen(QColor(0, 153, 0))
        self.pen.setWidth(3)

        self.series = QLineSeries(self)
        self.series.setPen(self.pen)

        self.x = np.arange(0, 2 * np.pi, 0.01)

        for i in self.x:
            self.series.append(i, np.sin(i))

        self.chart = QChart()
        self.chart.addSeries(self.series)
        self.chart.setAnimationOptions(QChart.SeriesAnimations)
        self.chart.setTitleFont(self.font)
        self.chart.setTitleBrush(QBrush(Qt.blue))
        self.chart.setTitle("Line Chart Demo")

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

        self.chartview = QChartView(self.chart)
        self.chartview.setRenderHint(QPainter.Antialiasing)

        self.axisX = QValueAxis()
        self.axisX.setRange(0, 2 * np.pi)
        self.axisX.setTickCount(6)
        self.axisX.setLabelFormat("%.1f")
        self.axisX.setTitleText("x")

        self.axisY = QValueAxis()
        self.axisY.setRange(0, 100)
        self.axisY.setLabelFormat("%d")
        self.axisY.setTitleText("sin(x)")

        self.chart.addAxis(self.axisX, Qt.AlignBottom)
        self.chart.addAxis(self.axisY, Qt.AlignLeft)

        self.setCentralWidget(self.chartview)
Exemple #10
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)
    def __createChart(self):
        self.__chart = QChart()
        self.ui.chartView.setChart(self.__chart)
        self.__chart.legend().setVisible(False)  #隐藏图例
        self.__chart.setMargins(QMargins(0, 0, 0, 0))  #把间距设置到最小

        #初始化线条数组
        series = [QLineSeries() for _ in range(15)]
        color = [
            '#FF88C2', '#FF8888', '#FFA488', '#FFBB66', '#FFDD55', '#FFFF77',
            '#DDFF77', '#BBFF66', '#66FF66', '#77FFCC', '#77FFEE', '#66FFFF',
            '#77DDFF', '#99BBFF', '#9999FF'
        ]

        #设置线条颜色形状
        pen = QPen()
        pen.setStyle(Qt.SolidLine)
        pen.setWidth(2)
        for i in range(15):
            pen.setColor(QColor(color[i]))
            series[i].setPen(pen)

        #向表格添加线条
        for i in range(15):
            self.__chart.addSeries(series[i])

        #设置坐标轴
        axisX = QValueAxis()
        #self.__curAxis=axisX       #当前坐标轴
        axisX.setRange(0, 200)  #设置坐标轴范围
        axisX.setLabelFormat("%d")  #标签格式
        axisX.setTickCount(5)  #主分隔个数
        axisX.setMinorTickCount(4)
        axisX.setGridLineVisible(True)
        axisX.setMinorGridLineVisible(False)

        axisY = QValueAxis()
        axisY.setRange(0, 1024)
        axisY.setLabelFormat("%d")  #标签格式
        axisY.setTickCount(5)
        axisY.setMinorTickCount(4)
        axisY.setGridLineVisible(True)
        axisY.setMinorGridLineVisible(False)

        self.__chart.addAxis(axisX, Qt.AlignBottom)  #坐标轴添加到图表,并指定方向
        self.__chart.addAxis(axisY, Qt.AlignLeft)

        for i in range(15):
            series[i].attachAxis(axisX)
            series[i].attachAxis(axisY)
Exemple #12
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
Exemple #13
0
    def set_y_aix(self, areas: []) -> QValueAxis:  # y轴坐标——面积
        ma = []
        for i in range(0, len(areas)):
            m = max(areas[i])
            ma.append(m)
        bound = max(ma)

        y_aix = QValueAxis()
        y_aix.setRange(0, int(bound))
        y_aix.setLabelFormat('%d')
        y_aix.setGridLineVisible(True)
        y_aix.setTickCount(11)
        y_aix.setMinorTickCount(4)

        return y_aix
Exemple #14
0
class CpuLineChart(QChart):

    def __init__(self, *args, **kwargs):
        super(CpuLineChart, self).__init__(*args, **kwargs)
        self.m_count = 10
        # 隐藏图例
        self.legend().hide()
        self.m_series = QSplineSeries(self)
        # 设置画笔
        self.m_series.setPen(QPen(QColor('#3B8CFF'), 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        self.addSeries(self.m_series)
        # x轴
        self.m_axisX = QDateTimeAxis(self)
        self.m_axisX.setTickCount(self.m_count + 1)  # 设置刻度数量
        self.m_axisX.setFormat('hh:mm:ss')  # 设置时间显示格式
        now = QDateTime.currentDateTime()  # 前10秒到现在
        self.m_axisX.setRange(now.addSecs(-self.m_count), now)
        self.addAxis(self.m_axisX, Qt.AlignBottom)
        self.m_series.attachAxis(self.m_axisX)
        # y轴
        self.m_axisY = QValueAxis(self)
        self.m_axisY.setLabelFormat('%d')  # 设置文本格式
        self.m_axisY.setMinorTickCount(4)  # 设置小刻度线的数目
        self.m_axisY.setTickCount(self.m_count + 1)
        self.m_axisY.setRange(0, 100)
        self.addAxis(self.m_axisY, Qt.AlignLeft)
        self.m_series.attachAxis(self.m_axisY)

        # 填充11个初始点,注意x轴 需要转为秒的时间戳
        self.m_series.append(
            [QPointF(now.addSecs(-i).toMSecsSinceEpoch(), 0) for i in range(self.m_count, -1, -1)])

        # 定时器获取数据
        self.m_timer = QTimer()
        self.m_timer.timeout.connect(self.update_data)
        self.m_timer.start(1000)

    def update_data(self):
        value = cpu_percent()
        now = QDateTime.currentDateTime()
        self.m_axisX.setRange(now.addSecs(-self.m_count), now)  # 重新调整x轴的时间范围
        # 获取原来的所有点,去掉第一个并追加新的一个
        points = self.m_series.pointsVector()
        points.pop(0)
        points.append(QPointF(now.toMSecsSinceEpoch(), value))
        # 替换法速度更快
        self.m_series.replace(points)
Exemple #15
0
    def setupChart(self):
        """Set up the GUI's graph line series type, chart instance, chart axes, 
        and chart view widget."""
        # Collect x and y data values from the CSV file
        x_values, y_values = self.loadCSVFile()

        # Create chart object
        chart = QChart()
        chart.setTitle(
            "Public Social Spending as a Share of GDP for Sweden, 1880 to 2016"
        )
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.legend().hide()  # Hide the chart's legend

        line_series = QLineSeries()  # Using line charts for this example
        #line_series.setPointLabelsVisible(True)
        #line_series.setPen(QColor(Qt.blue))

        # Loop through corresponding x and y values and add them to the line chart
        for value in range(0, self.row_count - 1):
            line_series.append(x_values[value], y_values[value])
        chart.addSeries(line_series)  # Add line series to chart instance

        # Specify parameters for the x and y axes
        axis_x = QValueAxis()
        axis_x.setLabelFormat("%i")
        axis_x.setTickCount(10)
        axis_x.setRange(1880, 2016)
        chart.addAxis(axis_x, Qt.AlignBottom)
        line_series.attachAxis(axis_x)

        axis_y = QValueAxis()
        axis_y.setLabelFormat("%i" + "%")
        axis_y.setRange(0, 40)
        chart.addAxis(axis_y, Qt.AlignLeft)
        line_series.attachAxis(axis_y)

        # Create QChartView object for displaying the chart
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.Antialiasing)

        # Create layout and set the layout for the window
        v_box = QVBoxLayout()
        v_box.addWidget(chart_view)
        self.setLayout(v_box)
    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 show_original_data(self):
        # Time domain
        y_data_scaled = np.interp(
            self.y_original, (self.y_original.min(), self.y_original.max()),
            (-10, +10))

        sample_size = len(self.y_original)
        self.x_data = np.linspace(0., 100., sample_size)

        points_1 = []

        for k in range(len(y_data_scaled)):
            points_1.append(QPointF(self.x_data[k], y_data_scaled[k]))

        self.m_series_1.replace(points_1)

        # Frequency domain
        y_freq_data = np.abs(fftpack.fft(self.y_original))
        y_freq_data = np.interp(y_freq_data,
                                (y_freq_data.min(), y_freq_data.max()),
                                (0, +10))
        x_freq_data = fftpack.fftfreq(len(
            self.y_original)) * self.sampling_rate

        axis_x = QValueAxis()
        axis_x.setRange(0, self.sampling_rate / 2)
        axis_x.setLabelFormat("%g")
        axis_x.setTitleText("Frequency [Hz]")

        axis_y = QValueAxis()
        axis_y.setRange(np.min(y_freq_data), np.max(y_freq_data))
        axis_y.setTitleText("Magnitude")

        self.m_chart_2.setAxisX(axis_x, self.m_series_2)
        self.m_chart_2.setAxisY(axis_y, self.m_series_2)

        points_2 = []

        for k in range(len(y_freq_data)):
            points_2.append(QPointF(x_freq_data[k], y_freq_data[k]))

        self.m_series_2.replace(points_2)

        self.m_series_3.clear()
        self.m_series_4.clear()
Exemple #18
0
    def update_graph(self, index):
        if index == 2:
            self.graph_chart.removeAllSeries()

            axis_x = QBarCategoryAxis()
            axis_x.setTitleText("日期")
            if self.graph_chart.axisX():
                self.graph_chart.removeAxis(self.graph_chart.axisX())
            self.graph_chart.addAxis(axis_x, Qt.AlignBottom)

            axis_y = QValueAxis()
            axis_y.setLabelFormat("%i")
            axis_y.setTitleText("售出量")
            if self.graph_chart.axisY():
                self.graph_chart.removeAxis(self.graph_chart.axisY())
            self.graph_chart.addAxis(axis_y, Qt.AlignLeft)

            max_num = 0
            total_date = 0
            set_dict = {}
            for key, data in sorted(self.graph_series.items(),
                                    key=lambda i: int(i[0])):
                axis_x.append(
                    QDateTime.fromSecsSinceEpoch(
                        int(key)).toString("yyyy年MM月dd日"))
                for set_name, value in data.items():
                    if set_name not in set_dict:
                        set_dict[set_name] = QBarSet(set_name)
                        for _ in range(total_date):
                            set_dict[set_name].append(0)
                    set_dict[set_name].append(value)
                    max_num = max(max_num, value)
                total_date += 1
                for _, bar_set in set_dict.items():
                    if bar_set.count() < total_date:
                        bar_set.append(0)
            bar_series = QBarSeries()
            for _, bar_set in set_dict.items():
                bar_series.append(bar_set)
            bar_series.hovered.connect(self.graph_tooltip)
            axis_y.setMax(max_num + 1)
            axis_y.setMin(0)
            self.graph_chart.addSeries(bar_series)
            bar_series.attachAxis(axis_x)
            bar_series.attachAxis(axis_y)
Exemple #19
0
    def update_axes(self):

        # Get and remove all axes
        for axis in self.chart.axes():
            self.chart.removeAxis(axis)

        # Create new axes
        # Create axis X
        axisx = QDateTimeAxis()
        axisx.setTickCount(5)
        axisx.setFormat("dd MMM yyyy hh:mm:ss")
        axisx.setTitleText("Date")
        self.chart.addAxis(axisx, Qt.AlignBottom)

        # Create axis Y
        axisY = QValueAxis()
        axisY.setTickCount(5)
        axisY.setLabelFormat("%.3f")
        axisY.setTitleText("Values")
        self.chart.addAxis(axisY, Qt.AlignLeft)
        # axisY.rangeChanged.connect(self.axis_range_changed)

        ymin = None
        ymax = None

        # Attach axes to series, find min-max
        for series in self.chart.series():
            series.attachAxis(axisx)
            series.attachAxis(axisY)
            vect = series.pointsVector()
            # for i in range(len(vect)):
            for i, _ in enumerate(vect):
                if ymin is None:
                    ymin = vect[i].y()
                    ymax = vect[i].y()
                else:
                    ymin = min(ymin, vect[i].y())
                    ymax = max(ymax, vect[i].y())

        # Update range
        # print('min max', ymin, ymax)
        if ymin is not None:
            axisY.setRange(ymin, ymax)
    def createChart(self):
        self.timeChart = QChart()
        titleFont = QFont()
        titleFont.setPixelSize(18)
        titleBrush = QBrush(QColor(0, 0, 255))
        self.timeChart.setTitleFont(titleFont)
        self.timeChart.setTitleBrush(titleBrush)
        self.timeChart.setTitle('Signal (Past ' + str(self.maxPoints) +
                                ' Samples)')
        # self.timeChart.addSeries(testseries)
        # self.timeChart.createDefaultAxes()
        self.timeChart.legend().hide()

        # Axis examples: https://doc.qt.io/qt-5/qtcharts-multiaxis-example.html
        newAxis = QValueAxis()
        newAxis.setMin(0)
        newAxis.setMax(self.maxPoints)
        newAxis.setTickCount(11)
        newAxis.setLabelFormat("%d")
        newAxis.setTitleText("Sample")
        self.timeChart.addAxis(newAxis, Qt.AlignBottom)

        newAxis = QValueAxis()
        newAxis.setMin(-100)
        newAxis.setMax(-10)
        newAxis.setTickCount(9)
        newAxis.setLabelFormat("%d")
        newAxis.setTitleText("dBm")
        self.timeChart.addAxis(newAxis, Qt.AlignLeft)

        chartBorder = Qt.darkGray
        self.timePlot = QChartView(self.timeChart, self)
        self.timePlot.setBackgroundBrush(chartBorder)
        self.timePlot.setRenderHint(QPainter.Antialiasing)

        self.timeSeries = QLineSeries()
        pen = QPen(Qt.yellow)

        pen.setWidth(2)
        self.timeSeries.setPen(pen)
        self.timeChart.addSeries(self.timeSeries)
        self.timeSeries.attachAxis(self.timeChart.axisX())
        self.timeSeries.attachAxis(self.timeChart.axisY())
 def __init__(self, data, type):
     super(BarChart, self).__init__()
     if type == self.BAR_CHART:
         self.brushes = (QColor(Qt.blue), QColor(Qt.red),
                         QBrush(Qt.blue, Qt.Dense5Pattern),
                         QBrush(Qt.red, Qt.Dense5Pattern))
         self.series = QBarSeries()
         axisY = QValueAxis()
         axisY.setRange(0, 5)
         axisY.setTickCount(6)
         axisY.setLabelFormat(" ")
         self.addAxis(axisY, Qt.AlignLeft)
     elif type == self.PERCENT_CHART:
         self.brushes = (QColor(Qt.yellow), QColor(255, 127,
                                                   0), QColor(Qt.red))
         self.series = QPercentBarSeries()
     self.setData(data)
     self.addSeries(self.series)
     self.series.attachAxis(self.axisX)
     if type == self.BAR_CHART: self.series.attachAxis(axisY)
Exemple #22
0
    def __init__(self):
        super().__init__()

        # thread
        self.worker = Worker()
        self.worker.price.connect(self.get_price)
        self.worker.start()

        # window size
        self.setMinimumSize(600, 400)

        # data
        self.series = QLineSeries()

        # chart object
        self.chart = QChart()
        self.chart.legend().hide()
        self.chart.addSeries(self.series)  # data feeding

        # axis
        axis_x = QDateTimeAxis()
        axis_x.setFormat("hh:mm:ss")

        dt = QDateTime.currentDateTime()
        axis_x.setRange(dt, dt.addSecs(128))

        self.chart.addAxis(axis_x, Qt.AlignBottom)
        self.series.attachAxis(axis_x)

        axis_y = QValueAxis()
        axis_y.setLabelFormat("%i")
        self.chart.addAxis(axis_y, Qt.AlignLeft)
        self.series.attachAxis(axis_y)

        # margin
        self.chart.layout().setContentsMargins(0, 0, 0, 0)

        # displaying chart
        chart_view = QChartView(self.chart)
        chart_view.setRenderHint(QPainter.Antialiasing)
        self.setCentralWidget(chart_view)
Exemple #23
0
    def _fill_chart(self, items: List[Run]):
        series = QLineSeries()
        series.setPointsVisible(True)
        series.setPointLabelsVisible(True)
        series.setPointLabelsFormat("@yPoint")
        series.hovered.connect(self.chart_view.show_series_tooltip)

        self.timestamp_by_run.clear()

        for run in items:
            date_value = calendar.timegm(run.date.timetuple()) * 1000
            total_issues = run.get_total_issues()
            series.append(date_value, total_issues)

            self.timestamp_by_run[date_value] = run

        chart = QChart()
        chart.setTheme(QChart.ChartThemeDark)
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.addSeries(series)
        chart.legend().hide()

        # No margin
        chart.layout().setContentsMargins(0, 0, 0, 0)
        chart.setBackgroundRoundness(0)

        axisX = QDateTimeAxis()
        axisX.setFormat("dd/MM/yyyy")
        axisX.setTitleText('Date')
        chart.addAxis(axisX, Qt.AlignBottom)
        series.attachAxis(axisX)

        axisY = QValueAxis()
        axisY.setLabelFormat('%d')
        axisY.setTitleText('Total issues')
        chart.addAxis(axisY, Qt.AlignLeft)
        series.attachAxis(axisY)

        self.chart_view.clear_all_tooltips()
        self.chart_view.setChart(chart)
Exemple #24
0
    def __init__(self):
        super().__init__()
        # window size
        self.setMinimumSize(600, 400)

        df = pyupbit.get_ohlcv("KRW-BTC")

        # data
        series = QLineSeries()
        for index in df.index:
            close = df.loc[index, 'close']
            dt = index.timestamp() * 1000       # msecs
            series.append(dt, close)

        # chart object
        chart = QChart()
        chart.legend().hide()
        chart.addSeries(series)         # data feeding

        # axis
        axis_x = QDateTimeAxis()
        axis_x.setFormat("yyyy-MM-dd")
        chart.addAxis(axis_x, Qt.AlignBottom)
        series.attachAxis(axis_x)

        axis_y = QValueAxis()
        axis_y.setLabelFormat("%i")
        chart.addAxis(axis_y, Qt.AlignLeft)
        series.attachAxis(axis_y)

        # margin
        chart.layout().setContentsMargins(0, 0, 0, 0)


        # displaying chart
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.Antialiasing)
        self.setCentralWidget(chart_view)
class MainWindow(QMainWindow):

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

    def initializeUI(self):
        """Initialize the window and display its contents."""
        self.setMinimumSize(1200, 600)
        self.setWindowTitle("3.1 - Data Visualization GUI")

        self.setupChart()
        self.setupToolsDockWidget()
        self.setupMenu()
        self.show()

    def setupChart(self):
        """Set up the GUI's graph series type, chart instance, chart axes, 
        and chart view widget."""
        random.seed(50) # Create seed for random numbers

        # Create the model instance and set the headers
        self.model = QStandardItemModel()
        self.model.setColumnCount(3)
        self.model.setHorizontalHeaderLabels(["Year", "Social Exp. %GDP", "Country"])

        # Collect x and y data values and labels from the CSV file
        xy_data_and_labels = self.loadCSVFile()

        # Create the individual lists for x, y and labels values
        x_values, y_values, labels = [], [], []
        # Append items to the corresponding lists
        for item in range(len(xy_data_and_labels)):
            x_values.append(xy_data_and_labels[item][0])
            y_values.append(xy_data_and_labels[item][1])
            labels.append(xy_data_and_labels[item][2])

        # Remove all duplicates from the labels list using list comprehension. 
        # This list will be used to create the labels in the chart's legend.
        set_of_labels = []
        [set_of_labels.append(x) for x in labels if x not in set_of_labels]  
    
        # Create chart object
        self.chart = QChart()
        self.chart.setTitle("Public Social Spending as a Share of GDP, 1880 to 2016")
        self.chart.legend().hide() # Hide legend at the start

        # Specify parameters for the x and y axes
        self.axis_x = QValueAxis()
        self.axis_x.setLabelFormat("%i")
        self.axis_x.setTickCount(10)
        self.axis_x.setRange(1880, 2016)
        self.chart.addAxis(self.axis_x, Qt.AlignBottom)

        self.axis_y = QValueAxis()
        self.axis_y.setLabelFormat("%i" + "%")
        self.axis_y.setRange(0, 40)
        self.chart.addAxis(self.axis_y, Qt.AlignLeft)

        # Create a Python dict to associate the labels with the individual line series
        series_dict = {}

        for label in set_of_labels:
            # Create labels from data and add them to a Python dictionary
            series_label = 'series_{}'.format(label)
            series_dict[series_label] = label # Create label value for each line series

        # For each of the keys in the dict, create a line series
        for keys in series_dict.keys():
            # Use get() to access the corresponding value for a key
            label = series_dict.get(keys)

            # Create line series instance and set its name and color values
            line_series = QLineSeries()
            line_series.setName(label)
            line_series.setColor(QColor(random.randint(10, 254), random.randint(10, 254), random.randint(10, 254)))

            # Append x and y coordinates to the series
            for value in range(len(xy_data_and_labels)):
                if line_series.name() == xy_data_and_labels[value][2]:
                    line_series.append(x_values[value], y_values[value])

                    # Create and add items to the model (for displaying the table)
                    items = [QStandardItem(str(item)) for item in xy_data_and_labels[value]]
                    color = line_series.pen().color()
                    for item in items:
                        item.setBackground(color)
                    self.model.insertRow(value, items)

            self.chart.addSeries(line_series)
            line_series.attachAxis(self.axis_x)
            line_series.attachAxis(self.axis_y)   

        # Create QChartView object for displaying the chart 
        self.chart_view = ChartView(self.chart)
        self.setCentralWidget(self.chart_view)

    def setupMenu(self):
        """Create a simple menu to manage the dock widget."""
        menu_bar = self.menuBar()
        menu_bar.setNativeMenuBar(False)

        # Create view menu and add actions
        view_menu = menu_bar.addMenu('View')
        view_menu.addAction(self.toggle_dock_tools_act)

    def setupToolsDockWidget(self):
        """Set up the dock widget that displays different tools and themes for 
        interacting with the chart. Also displays the data values in a table view object."""
        tools_dock = QDockWidget()
        tools_dock.setWindowTitle("Tools")
        tools_dock.setMinimumWidth(400)
        tools_dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        # Create widgets for dock widget area
        themes_cb = QComboBox()
        themes_cb.addItems(["Light", "Cerulean Blue", "Dark", "Sand Brown", 
            "NCS Blue", "High Contrast", "Icy Blue", "Qt"])
        themes_cb.currentTextChanged.connect(self.changeChartTheme)

        self.animations_cb = QComboBox()
        self.animations_cb.addItem("No Animation", QChart.NoAnimation)
        self.animations_cb.addItem("Grid Animation", QChart.GridAxisAnimations)
        self.animations_cb.addItem("Series Animation", QChart.SeriesAnimations)
        self.animations_cb.addItem("All Animations", QChart.AllAnimations)
        self.animations_cb.currentIndexChanged.connect(self.changeAnimations)

        self.legend_cb = QComboBox()
        self.legend_cb.addItem("No Legend")
        self.legend_cb.addItem("Align Left", Qt.AlignLeft)
        self.legend_cb.addItem("Align Top", Qt.AlignTop)
        self.legend_cb.addItem("Align Right", Qt.AlignRight)
        self.legend_cb.addItem("Align Bottom", Qt.AlignBottom)
        self.legend_cb.currentTextChanged.connect(self.changeLegend)

        self.antialiasing_check_box = QCheckBox()
        self.antialiasing_check_box.toggled.connect(self.toggleAntialiasing)

        reset_button = QPushButton("Reset Chart Axes")
        reset_button.clicked.connect(self.resetChartZoom)

        # Create table view and set its model
        data_table_view = QTableView()
        data_table_view.setModel(self.model)
        data_table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        data_table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)   

        dock_form = QFormLayout()
        dock_form.setAlignment(Qt.AlignTop)
        dock_form.addRow("Themes:", themes_cb)
        dock_form.addRow("Animations:", self.animations_cb)
        dock_form.addRow("Legend:", self.legend_cb)
        dock_form.addRow("Anti-Aliasing", self.antialiasing_check_box)
        dock_form.addRow(reset_button)
        dock_form.addRow(data_table_view)

        # Create QWidget object to act as a container for dock widgets
        tools_container = QWidget()
        tools_container.setLayout(dock_form)
        tools_dock.setWidget(tools_container)

        self.addDockWidget(Qt.LeftDockWidgetArea, tools_dock)
        # Handles the visibility of the dock widget
        self.toggle_dock_tools_act = tools_dock.toggleViewAction()

    def changeChartTheme(self, text):
        """Slot for changing the theme of the chart."""
        themes_dict = {"Light": 0, "Cerulean Blue": 1, "Dark": 2, "Sand Brown": 3, 
            "NCS Blue": 4, "High Contrast": 5, "Icy Blue": 6, "Qt": 7}
        theme = themes_dict.get(text)
        if theme == 0:
            self.setupChart()
        else:
            self.chart.setTheme(theme)
        
    def changeAnimations(self):
        """Slot for changing the animation style of the chart."""        
        animation = QChart.AnimationOptions(
            self.animations_cb.itemData(self.animations_cb.currentIndex()))
        self.chart.setAnimationOptions(animation)

    def changeLegend(self, text):
        """Slot for turning off the legend, or changing its location."""
        alignment = self.legend_cb.itemData(self.legend_cb.currentIndex())

        if text == "No Legend":
            self.chart.legend().hide()
        else:
            self.chart.legend().setAlignment(Qt.Alignment(alignment))
            self.chart.legend().show()

    def toggleAntialiasing(self, state):
        """If self.antialiasing_check_box.isChecked() is True, turn on antialiasing."""
        if state:
            self.chart_view.setRenderHint(QPainter.Antialiasing, on=True)
        else:
            self.chart_view.setRenderHint(QPainter.Antialiasing, on=False)

    def resetChartZoom(self):
        """Reset the chart and the axes."""
        self.chart.zoomReset()
        self.axis_x.setRange(1880, 2016)
        self.axis_y.setRange(0, 40)
            
    def loadCSVFile(self):
        """Load data from CSV file for the chart. 
        Select and store x and y values and labels into Python list objects.
        Return the xy_data_and_labels list."""
        file_name = "files/social_spending_simplified.csv"

        with open(file_name, "r") as csv_f:
            reader = csv.reader(csv_f)
            header_labels = next(reader)

            row_values = [] # Store current row values
            xy_data_and_labels = [] # Store all values

            for i, row in enumerate(reader):
                x = int(row[2])  
                y = float(row[3])   
                label = row[0]

                row_values.append(x)
                row_values.append(y)  
                row_values.append(label)

                # Add row_values to xy_data_and_labels, then reset row_values
                xy_data_and_labels.append(row_values)
                row_values = []

        return xy_data_and_labels
Exemple #26
0
def lines_stacked(name, table_df, x_bottom_cols, y_left_cols, y_right_cols,
                  legend_labels, tick_count):
    """
    折线堆叠图
    :param name: 图表名称
    :param table_df: 用于画图的pandas DataFrame对象
    :param x_bottom_cols:  下轴列索引列表
    :param y_left_cols: 左轴列索引列表
    :param y_right_cols: 右轴列索引列表
    :param legend_labels: 图例名称标签列表
    :param tick_count: 横轴刻度标签数
    :return: QChart实例
    """
    """ 过滤轴 """
    for y_left_col in y_left_cols:
        if is_datetime64_any_dtype(table_df[y_left_col]):  # 如果是时间轴
            y_left_cols.remove(y_left_col)
    for y_right_col in y_right_cols:
        if is_datetime64_any_dtype(table_df[y_right_col]):  # 如果是时间轴
            y_right_cols.remove(y_right_col)
    # 将x轴转为字符串
    x_bottom = x_bottom_cols[0]  # x轴列
    if is_datetime64_any_dtype(table_df[x_bottom]):  # 如果x轴是时间轴
        table_df[x_bottom] = table_df[x_bottom].apply(
            lambda x: x.strftime('%Y-%m-%d'))
    else:  # x轴非时间轴
        table_df[x_bottom] = table_df[x_bottom].apply(lambda x: str(x))
    font = QFont()  # 轴文字风格
    font.setPointSize(7)  # 轴标签文字大小
    chart = QChart()  # 图表实例
    chart.layout().setContentsMargins(0, 0, 0, 0)  # chart的外边距
    chart.setMargins(QMargins(15, 5, 15, 0))  # chart内边距
    chart.setTitle(name)  # chart名称
    """ x轴 """
    axis_x_bottom = QCategoryAxis(
        chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue)
    axis_x_bottom.setLabelsAngle(-90)  # 逆时针旋转90度
    axis_x_bottom.setLabelsFont(font)  # 设置字体样式
    axis_x_bottom.setGridLineVisible(False)  # 竖向连接线不可见
    chart.addAxis(axis_x_bottom, Qt.AlignBottom)  # 加入坐标x轴
    has_x_labels = False  # 收集x轴刻度的开关
    chart.x_labels = list()  # 绑定chart一个x轴的刻度列表
    """ 左Y轴 """
    axis_y_left = QValueAxis()
    axis_y_left.setLabelsFont(font)
    axis_y_left.setLabelFormat('%i')
    chart.addAxis(axis_y_left, Qt.AlignLeft)  # 图表加入左轴
    """ 右Y轴 """
    axis_y_right = QValueAxis()
    axis_y_right.setLabelsFont(font)
    axis_y_right.setLabelFormat('%.2f')
    chart.addAxis(axis_y_right, Qt.AlignRight)
    # 记录各轴的最值
    x_bottom_min, x_bottom_max = 0, table_df.shape[0]
    y_left_min, y_left_max = 0, 0
    y_right_min, y_right_max = 0, 0
    """ 根据左轴画折线 """
    for y_left_col in y_left_cols:  # 根据左轴画折线
        # 计算做轴的最值用于设置范围
        table_df[y_left_col] = table_df[y_left_col].apply(
            covert_float)  # y轴列转为浮点数值
        # 获取最值
        y_min, y_max = table_df[y_left_col].min(), table_df[y_left_col].max()
        if y_min < y_left_min:
            y_left_min = y_min
        if y_max > y_left_max:
            y_left_max = y_max
        # 取得图线的源数据作折线图
        left_line_data = table_df.iloc[:, [x_bottom, y_left_col]]
        series = QLineSeries()
        series.setName(legend_labels[y_left_col])
        for position_index, point_item in enumerate(
                left_line_data.values.tolist()):
            series.append(position_index, point_item[1])  # 取出源数据后一条线就2列数据
            # 收集坐标标签
            if not has_x_labels:
                chart.x_labels.append(point_item[0])
        chart.addSeries(series)  # 折线入图
        series.attachAxis(axis_x_bottom)
        series.attachAxis(axis_y_left)
    # 左轴范围
    axis_y_left.setRange(y_left_min, y_left_max)
    """ 根据右轴画折线 """
    for y_right_col in y_right_cols:  # 根据右轴画折线
        # 计算做轴的最值用于设置范围
        table_df[y_right_col] = table_df[y_right_col].apply(
            covert_float)  # y轴列转为浮点数值
        # 获取最值
        y_min, y_max = table_df[y_right_col].min(), table_df[y_right_col].max()
        if y_min < y_right_min:
            y_right_min = y_min
        if y_max > y_right_max:
            y_right_max = y_max
        # 取得图线的源数据作折线图
        left_line_data = table_df.iloc[:, [x_bottom, y_right_col]]
        series = QLineSeries()
        series.setName(legend_labels[y_right_col])
        for position_index, point_item in enumerate(
                left_line_data.values.tolist()):
            series.append(position_index, point_item[1])  # 取出源数据后一条线就2列数据
        chart.addSeries(series)
        series.attachAxis(axis_x_bottom)
        series.attachAxis(axis_y_right)
    # 右轴范围
    axis_y_right.setRange(y_right_min, y_right_max)
    # 设置下轴刻度标签
    # print('x轴最大值', x_bottom_max)
    x_bottom_interval = int(x_bottom_max / (tick_count - 1))
    if x_bottom_interval == 0:
        for i in range(0, x_bottom_max):
            axis_x_bottom.append(chart.x_labels[i], i)
    else:
        for i in range(0, x_bottom_max, x_bottom_interval):
            axis_x_bottom.append(chart.x_labels[i], i)
    chart.legend().setAlignment(Qt.AlignBottom)
    return chart
Exemple #27
0
class QmyMainWindow(QMainWindow): 

   def __init__(self, parent=None):
      super().__init__(parent)   #调用父类构造函数,创建窗体
      self.ui=Ui_MainWindow()    #创建UI对象
      self.ui.setupUi(self)      #构造UI界面

      self.setWindowTitle("Demo12_7, QAreaSeries绘制填充图")
      self.__buildStatusBar()
      self.ui.chartView.setRenderHint(QPainter.Antialiasing)
      self.ui.chartView.setCursor(Qt.CrossCursor)  #设置鼠标指针为十字星
      self.ui.chartView.mouseMove.connect(self.do_chartView_mouseMove)

      self.__colorLine=Qt.darkBlue      #曲线颜色,darkBlue
      self.__colorFill=Qt.darkBlue      #填充颜色 gray
      self.__iniChart()       #创建self.chart
##  "填充类型"4个RadioButton关联槽函数
      self.ui.radioFill_Pos.clicked.connect(self.do_redrawFill)   #positive
      self.ui.radioFill_Neg.clicked.connect(self.do_redrawFill)   #negative
      self.ui.radioFill_Both.clicked.connect(self.do_redrawFill)  #both
      self.ui.radioFill_None.clicked.connect(self.do_redrawWave)  #wiggle
      

##  ==============自定义功能函数========================
   def __buildStatusBar(self):
      self.__labFileName = QLabel("数据文件")     
      self.__labFileName.setMinimumWidth(200)
      self.ui.statusBar.addWidget(self.__labFileName)

      self.__labChartXY = QLabel("Chart, X=, Y=") 
      self.__labChartXY.setMinimumWidth(200)
      self.ui.statusBar.addWidget(self.__labChartXY)
      
      self.__labAreaXY = QLabel("AreaSeries,X=, Y=") 
      self.__labAreaXY.setMinimumWidth(200)
      self.ui.statusBar.addWidget(self.__labAreaXY)

   def __iniChart(self):
      self.chart = QChart()    #创建 chart
      self.chart.setTitle("地震波形")
      self.chart.legend().setVisible(False)  #不显示图例
      self.ui.chartView.setChart(self.chart) #chart添加到chartView
## 创建坐标轴X
      self.__axisX = QValueAxis()   # bottom 轴是 QValueAxis
      self.__axisX.setTitleText("时间(秒)")
      self.__axisX.setRange(0, 10)
      self.__axisX.setTickCount(10)
      self.__axisX.setLabelFormat("%.2f")  #标签格式
      self.chart.addAxis(self.__axisX,Qt.AlignBottom)
## 创建坐标轴Y
      self.__axisY = QValueAxis()   # left 轴是 QValueAxis
      self.__axisY.setTitleText("幅度")
      self.__axisY.setRange(-5,5)
      self.__axisY.setTickCount(5)
      self.__axisY.setLabelFormat("%.2f")  #标签格式
      self.chart.addAxis(self.__axisY,Qt.AlignLeft)

##  ==============event处理函数==========================
        
        
##  ==========由connectSlotsByName()自动连接的槽函数============        
##=====工具栏 按钮功能
   @pyqtSlot()    ##“打开文件”按钮
   def on_actOpen_triggered(self):
      curPath=QDir.currentPath()    #获取当前路径
      filename,flt=QFileDialog.getOpenFileName(self,"打开一个文件",curPath,
                  "地震数据文件(*.txt);;所有文件(*.*)")
      if (filename==""):
         return

      aFile=open(filename,'r')
      allLines=aFile.readlines()  #读取所有行,list类型,每行末尾带有 \n
      aFile.close()
      fileInfo=QFileInfo(filename)
      QDir.setCurrent(fileInfo.absolutePath())
      self.__labFileName.setText("数据文件:"+fileInfo.fileName())
      
      rowCnt=len(allLines)    #行数,即数据点数
      self.__vectData=[0]*rowCnt   #列表
      for i in range(rowCnt):      
         lineText=allLines[i].strip()  #字符串表示的数字
         self.__vectData[i]=float(lineText)
      minV=min(self.__vectData)  #最小值
      self.ui.spinY_Min.setValue(minV)
      maxV=max(self.__vectData)  #最大值
      self.ui.spinY_Max.setValue(maxV)
      
      if self.ui.radioFill_None.isChecked():
         self.do_redrawWave()    #绘制波形曲线
      else:
         self.do_redrawFill()    #绘制有填充的波形
      self.ui.frameSetup.setEnabled(True)

   @pyqtSlot()
   def on_actZoomIn_triggered(self):
      self.ui.chartView.chart().zoom(1.2)
      
   @pyqtSlot()
   def on_actZoomOut_triggered(self):
      self.ui.chartView.chart().zoom(0.8)

   @pyqtSlot()
   def on_actZoomReset_triggered(self):
      self.ui.chartView.chart().zoomReset()
      
##   Y轴设置      
   @pyqtSlot()    ##设置坐标范围
   def on_btnY_SetRange_clicked(self):
      self.__axisY.setRange(self.ui.spinY_Min.value(),
                            self.ui.spinY_Max.value())
   @pyqtSlot(int)    ##分度数
   def on_spinY_Ticks_valueChanged(self,arg1):
      self.__axisY.setTickCount(arg1)

   @pyqtSlot(bool)  ##显示网格线
   def on_chkBoxY_GridLine_clicked(self,checked):
      self.__axisY.setGridLineVisible(checked)
      
##    X轴设置
   @pyqtSlot()       ##设置坐标范围
   def on_btnX_SetRange_clicked(self):
      self.__axisX.setRange(self.ui.spinX_Min.value(),
                            self.ui.spinX_Max.value())
   @pyqtSlot(int)    ##分度数
   def on_spinX_Ticks_valueChanged(self,arg1):
      self.__axisX.setTickCount(arg1)

   @pyqtSlot(bool)   ##显示网格线
   def on_chkBoxX_GridLine_clicked(self,checked):
      self.__axisX.setGridLineVisible(checked)
      
           
##  =============自定义槽函数===============================        
   @pyqtSlot()    ##绘制原始波形曲线
   def do_redrawWave(self):
      self.chart.removeAllSeries()  # 删除所有序列
      pen=QPen(self.__colorLine)    # 曲线颜色
      pen.setWidth(2)
      seriesWave = QLineSeries() 
      seriesWave.setUseOpenGL(True) 
      seriesWave.setPen(pen)

      vx=0
      intv=0.001  #1000Hz采样
      pointCount=len(self.__vectData)
      for i in range(pointCount):
         value=self.__vectData[i]
         seriesWave.append(vx,value)
         vx =vx+ intv
      self.__axisX.setRange(0,vx)

      self.chart.addSeries(seriesWave)
      seriesWave.attachAxis(self.__axisX)
      seriesWave.attachAxis(self.__axisY)
      

   @pyqtSlot()    ##绘制3种填充曲线
   def do_redrawFill(self):
      self.chart.removeAllSeries()  #删除所有序列
      pen=QPen(self.__colorLine)    #线条颜色
      pen.setWidth(2)

      seriesFullWave = QLineSeries()      #全波形
      seriesFullWave.setUseOpenGL(True)
      seriesFullWave.setPen(pen)

      seriesPositive = QLineSeries()      #正半部分曲线
      seriesPositive.setUseOpenGL(True)
      seriesPositive.setVisible(False)    #不显示

      seriesNegative = QLineSeries()      #负半部分曲线
      seriesNegative.setUseOpenGL(True)
      seriesNegative.setVisible(False)    #不显示即可

      seriesZero = QLineSeries()          #零均值线
      seriesZero.setUseOpenGL(True)
      seriesZero.setVisible(False)        #不显示即可

   ## 填充数据
      vx=0
      intv=0.001   #1000Hz采样,数据点间隔时间
      pointCount=len(self.__vectData)
      for i in range(pointCount):
         value=self.__vectData[i]
         seriesFullWave.append(vx,value)  #完整波形
         seriesZero.append(vx,0)          #零值线
         if value>0:
            seriesPositive.append(vx,value)  #正半部分波形
            seriesNegative.append(vx,0)
         else:
            seriesPositive.append(vx,0)
            seriesNegative.append(vx,value) #负半部分波形
         vx =vx+intv

      self.__axisX.setRange(0,vx)

   ##  创建QAreaSeries序列,设置上、下界的QLineSeries对象
      pen.setStyle(Qt.NoPen)  #无线条,隐藏填充区域的边线
      if self.ui.radioFill_Pos.isChecked():     #positive fill
         series = QAreaSeries(seriesPositive, seriesZero) #QAreaSeries
         series.setColor(self.__colorFill)      #填充色
         series.setPen(pen)   #不显示线条
         self.chart.addSeries(series)
         series.attachAxis(self.__axisX)
         series.attachAxis(self.__axisY)
         
      elif self.ui.radioFill_Neg.isChecked():  #negative fill
         series = QAreaSeries(seriesZero,seriesNegative)
         series.setColor(self.__colorFill)
         series.setPen(pen)   #不显示线条
         self.chart.addSeries(series)
         series.attachAxis(self.__axisX)
         series.attachAxis(self.__axisY)

      elif self.ui.radioFill_Both.isChecked():  #both fill
         series = QAreaSeries(seriesZero,seriesFullWave)
         series.setColor(self.__colorFill)
         series.setPen(pen)   #不显示线条
         self.chart.addSeries(series)
         series.attachAxis(self.__axisX)
         series.attachAxis(self.__axisY)

      series.clicked.connect(self.do_area_clicked)  #关联槽函数
         
   ## 构建QAreaSeries的两个QLineSeries序列必须添加到chart里,否则程序崩溃
      self.chart.addSeries(seriesZero)       #隐藏
      self.chart.addSeries(seriesPositive)   #隐藏
      self.chart.addSeries(seriesNegative)   #隐藏
      self.chart.addSeries(seriesFullWave)   #全波形曲线,显示

      seriesPositive.attachAxis(self.__axisX)
      seriesPositive.attachAxis(self.__axisY)

      seriesNegative.attachAxis(self.__axisX)
      seriesNegative.attachAxis(self.__axisY)

      seriesZero.attachAxis(self.__axisX)
      seriesZero.attachAxis(self.__axisY)
      
      seriesFullWave.attachAxis(self.__axisX)
      seriesFullWave.attachAxis(self.__axisY)

   def do_chartView_mouseMove(self,point):
      pt=self.ui.chartView.chart().mapToValue(point)  #QPointF 转换为图表的数值
      self.__labChartXY.setText("Chart X=%.2f,Y=%.2f"%(pt.x(),pt.y()))  #状态栏显示

   def do_area_clicked(self,point):
      self.__labAreaXY.setText("AreaSeries X=%.2f,Y=%.2f"
                               %(point.x(),point.y()))   #状态栏显示
Exemple #28
0
    # [3] create the chart
    chart = QChart()
    chart.addSeries(series)
    chart.setTitle("Sunspots count (by Space Weather Prediction Center)")
    # [3]

    # [4]
    axisX = QDateTimeAxis()
    axisX.setTickCount(10)
    axisX.setFormat("MMM yyyy")
    axisX.setTitleText("Date")
    chart.addAxis(axisX, Qt.AlignBottom)
    series.attachAxis(axisX)

    axisY = QValueAxis()
    axisY.setLabelFormat("%i")
    axisY.setTitleText("Sunspots count")
    chart.addAxis(axisY, Qt.AlignLeft)
    series.attachAxis(axisY)
    # [4]

    # [5] prepare the chart view
    chartView = QChartView(chart)
    chartView.setRenderHint(QPainter.Antialiasing)
    # [5]

    # [6] show the main window
    window = QMainWindow()
    window.setCentralWidget(chartView)
    window.resize(800, 600)
    window.show()
Exemple #29
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, 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)
Exemple #30
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)
Exemple #31
0
def bars_stacked(name, table_df, x_bottom_cols, y_left_cols, y_right_cols,
                 legend_labels, tick_count):
    """
    柱形堆叠图
    :param name: 图表名称
    :param table_df: 用于画图的pandas DataFrame对象
    :param x_bottom_cols:  下轴列索引列表
    :param y_left_cols: 左轴列索引列表
    :param y_right_cols: 右轴列索引列表
    :param legend_labels: 图例名称标签列表
    :param tick_count: 横轴刻度标签数
    :return: QChart实例
    """
    """ 过滤轴 """
    for y_left_col in y_left_cols:
        if is_datetime64_any_dtype(table_df[y_left_col]):  # 如果是时间轴
            y_left_cols.remove(y_left_col)
    for y_right_col in y_right_cols:
        if is_datetime64_any_dtype(table_df[y_right_col]):  # 如果是时间轴
            y_right_cols.remove(y_right_col)
    # 将x轴转为字符串
    x_bottom = x_bottom_cols[0]  # x轴列
    if is_datetime64_any_dtype(table_df[x_bottom]):  # 如果x轴是时间轴
        table_df[x_bottom] = table_df[x_bottom].apply(
            lambda x: x.strftime('%Y-%m-%d'))
    else:  # x轴非时间轴
        table_df[x_bottom] = table_df[x_bottom].apply(lambda x: str(x))
    font = QFont()  # 轴文字风格
    font.setPointSize(7)  # 轴标签文字大小
    chart = QChart()  # 图表实例
    chart.layout().setContentsMargins(0, 0, 0, 0)  # chart的外边距
    chart.setMargins(QMargins(15, 5, 15, 0))  # chart内边距
    chart.setTitle(name)  # chart名称
    """ x轴 """
    axis_x_bottom = QCategoryAxis(
        chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue)
    axis_x_bottom.setLabelsAngle(-90)  # 逆时针旋转90度
    axis_x_bottom.setLabelsFont(font)  # 设置字体样式
    axis_x_bottom.setGridLineVisible(False)  # 竖向连接线不可见
    # chart.addAxis(axis_x_bottom, Qt.AlignBottom)  # 加入坐标x轴
    has_x_labels = False  # 收集x轴刻度的开关
    chart.x_labels = list()  # 绑定chart一个x轴的刻度列表
    """ 左Y轴 """
    axis_y_left = QValueAxis()
    axis_y_left.setLabelsFont(font)
    axis_y_left.setLabelFormat('%i')
    chart.addAxis(axis_y_left, Qt.AlignLeft)  # 图表加入左轴
    """ 右Y轴 """
    axis_y_right = QValueAxis()
    axis_y_right.setLabelsFont(font)
    axis_y_right.setLabelFormat('%.2f')
    chart.addAxis(axis_y_right, Qt.AlignRight)
    # 记录各轴的最值
    x_bottom_min, x_bottom_max = 0, table_df.shape[0]
    y_left_min, y_left_max = 0, 0
    y_right_min, y_right_max = 0, 0
    # 柱形图
    left_bars = QBarSeries()
    """ 根据左轴画柱形 """
    for y_left_col in y_left_cols:  # 根据左轴画折线
        # 计算做轴的最值用于设置范围
        table_df[y_left_col] = table_df[y_left_col].apply(
            covert_float)  # y轴列转为浮点数值
        # 获取最值
        y_min, y_max = table_df[y_left_col].min(), table_df[y_left_col].max()
        if y_min < y_left_min:
            y_left_min = y_min
        if y_max > y_left_max:
            y_left_max = y_max
        # 取得图表的源数据作柱形
        left_bar_data = table_df.iloc[:, [x_bottom, y_left_col]]
        bar = QBarSet(legend_labels[y_left_col])
        bar.setPen(QPen(Qt.transparent))  # 设置画笔轮廓线透明(数据量大会出现空白遮住柱形)
        for index, point_item in enumerate(left_bar_data.values.tolist()):
            bar.append(point_item[1])
            if not has_x_labels:
                chart.x_labels.append(point_item[0])
        has_x_labels = True  # 关闭添加轴标签
        left_bars.append(bar)  # 柱形加入系列
    left_bars.attachAxis(axis_y_left)
    # 左轴的范围
    axis_y_left.setRange(y_left_min, y_left_max)
    """ 根据右轴画柱形 """
    right_bars = QBarSeries()
    for y_right_col in y_right_cols:  # 根据右轴画柱形
        # 计算做轴的最值用于设置范围
        table_df[y_right_col] = table_df[y_right_col].apply(
            covert_float)  # y轴列转为浮点数值
        # 获取最值
        y_min, y_max = table_df[y_right_col].min(), table_df[y_right_col].max()
        if y_min < y_right_min:
            y_right_min = y_min
        if y_max > y_right_max:
            y_right_max = y_max
        # 取得图线的源数据作折线图
        right_bar_data = table_df.iloc[:, [x_bottom, y_right_col]]
        bar = QBarSet(legend_labels[y_right_col])
        bar.setPen(QPen(Qt.transparent))
        for position_index, point_item in enumerate(
                right_bar_data.values.tolist()):
            bar.append(point_item[1])  # 取出源数据后一条线就2列数据
        right_bars.append(bar)
        right_bars.attachAxis(axis_x_bottom)
        right_bars.attachAxis(axis_y_right)
    # 右轴范围
    axis_y_right.setRange(y_right_min, y_right_max)
    chart.addSeries(left_bars)  # 左轴的柱形图加入图表
    # print(right_bars.count())
    if right_bars.count() != 0:  # 为空时加入会导致空位
        chart.addSeries(right_bars)
    chart.setAxisX(axis_x_bottom, left_bars)  # 关联设置x轴
    # 横轴标签设置
    x_bottom_interval = int(x_bottom_max / (tick_count - 1))
    if x_bottom_interval == 0:
        for i in range(0, x_bottom_max):
            axis_x_bottom.append(chart.x_labels[i], i)
    else:
        for i in range(0, x_bottom_max, x_bottom_interval):
            axis_x_bottom.append(chart.x_labels[i], i)
    chart.legend().setAlignment(Qt.AlignBottom)
    return chart