一、QBarSeries简介1. 官方描述
https://doc.qt.io/qtforpython-6/PySide6/QtCharts/QBarSeries.html
【译注:官方文档内容过于简洁,表明完全仅继承了QAbstractBarSeries,且没有扩展任何属性、方法和信号。因此,直接参考QAbstractBarSeries的文档:】
https://doc.qt.io/qtforpython-6/PySide6/QtCharts/QAbstractBarSeries.html
在条形图中,条形被定义为每个类别(category,x轴划分的一个区间)包含一个数据值的条形集合(bar set)。条形的位置由类别指定,其高度由数据值指定。包含多个条形集合的条形序列(bar series)将属于同一类别的条形组合在一起。条形图的样式由所选的 QAbstractBarSeries 子类 ( QBarSeries, QStackedBarSeries, QPercentBarSeries, QHorizontalStackedBarSeries, QHorizontalPercentBarSeries, QHorizontalBarSeries ) 来决定。
1.1 属性
属性 | 描述 |
---|---|
barWidth | 序列中条形的宽度 |
count | 序列中条形集合的数量 |
labelsAngle | 数值标签的角度(单位为度)。数值标签是标注在条形上,表示该条形的值的标签 |
labelsFormat | 数值标签的显示格式。通过 setLabelsFormat(str) 方法实现,入参字符串中通过’@value’表示引用数值。一个例子:setLabelsFormat(‘@value km’) |
labelsPosition | 数值标签的位置 |
labelsPrecision | 数值标签中显示的最大有效位数 |
labelsVisible | 数值标签的可见性。默认为False |
1.2 信号
信号 | 描述 |
---|---|
hovered(status, index, barset) | 鼠标悬停到条形,或离开条形时触发,发送三个数据。鼠标悬停到条形时,status为True,离开时为False;index的值为条形在条形组(bar set)中的编号;barset的值为对应的QBarSet对象。可以通过 QBarSet.label() 获取该条形组的名称,还可以通过 QBarSet.at(index) 获取该条形的数值 |
2. 官方用例
https://doc.qt.io/qtforpython-6/examples/example_charts_barchart.html
该用例绘制了每组包含5种数据的条形图。
2.1 创建条形图
# Copyright (C) 2022 The Qt Company Ltd.# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause"""PySide6 port of the linechart example from Qt v6.x"""import sysfrom PySide6.QtCharts import (QBarCategoryAxis, QBarSeries, QBarSet, QChart, QChartView, QValueAxis)from PySide6.QtCore import Qtfrom PySide6.QtGui import QPainterfrom PySide6.QtWidgets import QApplication, QMainWindowclass TestChart(QMainWindow): def __init__(self): super().__init__() # 创建QBarSet。每组条形有5种数据,因此需要创建5个 self.set_0 = QBarSet("Jane") self.set_1 = QBarSet("John") self.set_2 = QBarSet("Axel") self.set_3 = QBarSet("Mary") self.set_4 = QBarSet("Samantha") # 向各QBarSet添加数据 self.set_0.append([1, 2, 3, 4, 5, 6]) self.set_1.append([5, 0, 0, 4, 0, 7]) self.set_2.append([3, 5, 8, 13, 8, 5]) self.set_3.append([5, 6, 7, 3, 4, 5]) self.set_4.append([9, 7, 5, 3, 1, 2]) # 创建QBarSeries,并将QBarSet加入其中 self.series = QBarSeries() self.series.append(self.set_0) self.series.append(self.set_1) self.series.append(self.set_2) self.series.append(self.set_3) self.series.append(self.set_4) # 创建QCahrt,并与QBarSeries绑定 self.chart = QChart() self.chart.addSeries(self.series) self.chart.setTitle("Simple barchart example") self.chart.setAnimationOptions(QChart.SeriesAnimations) # 不同于QXYSeries,条形图的x轴标签直接与QBarCategoryAxis绑定 self.categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] self.axis_x = QBarCategoryAxis() self.axis_x.append(self.categories) # 将x轴先后与QChart、QBarSeries绑定 self.chart.addAxis(self.axis_x, Qt.AlignBottom) self.series.attachAxis(self.axis_x) self.axis_y = QValueAxis() self.axis_y.setRange(0, 15) # 将y轴先后与QChart、QBarSeries绑定 self.chart.addAxis(self.axis_y, Qt.AlignLeft) self.series.attachAxis(self.axis_y) self.chart.legend().setVisible(True) self.chart.legend().setAlignment(Qt.AlignBottom) self._chart_view = QChartView(self.chart) self._chart_view.setRenderHint(QPainter.Antialiasing) self.setCentralWidget(self._chart_view)if __name__ == "__main__": app = QApplication(sys.argv) window = TestChart() window.show() window.resize(420, 300) sys.exit(app.exec())
二、实践1. 用例说明
用每日收支数据绘制条形图。
2. 代码实现
from PySide6.QtCharts import QChart, QChartView, QBarSet, QBarSeries, QBarCategoryAxisfrom PySide6.QtGui import QPainterfrom PySide6.QtCore import Qt, QDateTimefrom PySide6.QtWidgets import QApplication, QMainWindowapp = QApplication([])window = QMainWindow()chart = QChart()chart.setTitle('收支统计')# 准备数据axisX_date = [QDateTime.currentDateTime().addDays(i) for i in range(5)]axisY_value1 = [10 - 2 * i for i in range(5)]axisY_value2 = [5 + i * (-1) ** i for i in range(5)]# 创建条形图集合set【每个set都是条形图中一种待展示的数据类别】bar_set_expense = QBarSet('支出')bar_set_income = QBarSet('收入')# 将值传入条形图集合set【通过列表的形式,存入某种数据类别的一组数值】for i in range(5): bar_set_expense.append(axisY_value1[i]) bar_set_income.append(axisY_value2[i])# 创建条形图序列series【series只与QChart有关,而与待展示数据的种类无关,因此只需创建一个】bar_series = QBarSeries()# 将数据集合存入seriesbar_series.append(bar_set_expense)bar_series.append(bar_set_income)# 将series加入chartchart.addSeries(bar_series)# 尝试另一种坐标创建方法:先创建默认坐标系,再创建自定义坐标轴,最后仅替换对应的坐标轴chart.createDefaultAxes()# 创建条形图坐标轴axis_x = QBarCategoryAxis()# 必须是字符串列表,以便得到预期格式axis_x.append([date.toString("yyyy/MM/dd") for date in axisX_date])# 替换原x轴chart.removeAxis(chart.axes(Qt.Orientation.Horizontal)[0])chart.addAxis(axis_x, Qt.AlignBottom)bar_series.attachAxis(axis_x)# 【注意】也许你会在网上看到如下方法的使用。具体情况参考“三、问题与总结”# 未来将不支持的方法:chart.removeAxis(chart.axisX())# 未来将不支持的方法:chart.setAxisX(axis_x, bar_series)# 显示图表chartView = QChartView(chart)chartView.setRenderHint(QPainter.Antialiasing)window.setCentralWidget(chartView)window.show()app.exec()
三、问题与总结1. DeprecationWarning: Function: ‘QChart.axisX(QAbstractSeries * series) const’ is marked as deprecated, please check the documentation for more information问题描述
当调用QChart.axisX()
、Qchart.setAxisX()
等方法时,得到该警告。原因是这些方法被标记为“不支持的方法”,应当通过其他方法实现。
解决方法对于QChart.axisX()
替换为:
# definationdef Qchart.axes(self, orientation: Orientation, series: QAbstractSeries | None) -> list[QAbstractAxis]# example: 获取第一个水平坐标轴axis_x = chart.axes(Qt.Orientation.Horizontal)[0]
对于QChart.setAxisX()
没有对应的方法可以替代,但可以更改为以下几个步骤:
# definationchart.removeAxis(chart.axes(Qt.Orientation.Horizontal)[0])chart.addAxis(axis_x, Qt.AlignBottom)series.attachAxis(axis_x)
2. 更新条形图的正确代码顺序问题描述
当需要展示多种意义的数据时,不同于QXYSeries及其派生类序列,条形图QChart只需与一个QBarSeries绑定。在这个唯一的QBarSeries中,多种意义的数据通过多个QBarSet表示。
当更新条形图时,只需更新QBarSeries内的各个QBarSet(与其说是更新,更像是丢弃重造)。因此,实现该过程的代码会与QXYSeries类的图表有所差异(主要在于数据传入的部分)。
解决方法
- 清除 QBarSeries 对象中的旧数据,即调用
QBarSeries.clear()
- 对于每种数据,创建 QBarSet 对象,并将数据写入 QBarSet 对象, 即调用
QBarSet.append()
- 将每个 QBarSet 对象加入 QBarSeries 对象, 即调用
QBarSeries.append()
- 【仅需一次】将 QBarSeries 对象与 QChart 对象绑定,即调用
QChart.addSeries()
- 删除旧坐标轴 QAbstractAxis 对象,并重新创建。其中,x轴为 QBarCategoryAxis 对象
- 将新 QAbstractAxis 对象与 QChart 对象绑定,即调用
QChart.addAxis()
- 将新 QAbstractAxis 对象与 QBarSeries 对象绑定,即调用
QBarSeries.attachAxis()
本文来自博客园,作者:林风冰翼,转载请注明原文链接:https://www.cnblogs.com/LinfengBingyi/p/17816325.html