一、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 sys from PySide6.QtCharts import (QBarCategoryAxis, QBarSeries, QBarSet, QChart,
QChartView, QValueAxis)
from PySide6.QtCore import Qt
from PySide6.QtGui import QPainter
from PySide6.QtWidgets import QApplication, QMainWindow class 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, QBarCategoryAxis
from PySide6.QtGui import QPainter
from PySide6.QtCore import Qt, QDateTime
from PySide6.QtWidgets import QApplication, QMainWindow app = 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()
# 将数据集合存入series
bar_series.append(bar_set_expense)
bar_series.append(bar_set_income) # 将series加入chart
chart.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()

替换为:

# defination
def Qchart.axes(self, orientation: Orientation,
series: QAbstractSeries | None) -> list[QAbstractAxis] # example: 获取第一个水平坐标轴
axis_x = chart.axes(Qt.Orientation.Horizontal)[0]

对于QChart.setAxisX()

没有对应的方法可以替代,但可以更改为以下几个步骤:

# defination
chart.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()

【PySide6】QChart笔记(二)—— QBarSeries的使用的更多相关文章

  1. 《CMake实践》笔记二:INSTALL/CMAKE_INSTALL_PREFIX

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  2. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  3. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  4. Python 学习笔记二

    笔记二 :print 以及基本文件操作 笔记一已取消置顶链接地址 http://www.cnblogs.com/dzzy/p/5140899.html 暑假只是快速过了一遍python ,现在起开始仔 ...

  5. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  6. webpy使用笔记(二) session/sessionid的使用

    webpy使用笔记(二) session的使用 webpy使用系列之session的使用,虽然工作中使用的是django,但是自己并不喜欢那种大而全的东西~什么都给你准备好了,自己好像一个机器人一样赶 ...

  7. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  8. 《MFC游戏开发》笔记二 建立工程、调整窗口

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9300383 作者:七十一雾央 新浪微博:http:/ ...

  9. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  10. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

随机推荐

  1. Vue: 配置axios基准路径并使用

    配置 main.js文件修改 在main.js中进行如下修改 // 设置axios全局api import axios from 'axios' // 请求基准路径的配置 后台 axios.defau ...

  2. 关于zbar

    python3不支持zbar,可以使用pyzbar python2支持zbar

  3. 整理不错的opencv博客

    https://me.csdn.net/column/u013095718 更全的博客: https://blog.csdn.net/zhmxy555/column/info/opencv-tutor ...

  4. 利用pytorch准备数据集、构建与训练、保存与加载CNN模型

    本文的主要内容是利用pytorch框架与torchvision工具箱,进行准备数据集.构建CNN网络模型.训练模型.保存和加载自定义模型等工作.本文若有疏漏.需更正.改进的地方,望读者予以指正,如果本 ...

  5. PXE操作过程 kickstart 无人值守安装

    PXE操作过程 分配给同一局域网内新加机器的地址(配置文件) dhcp 分配地址 指明tftp 服务器的地址 tftp服务端开启 udp 配置 默认关闭 安装syslinux 取得 pxelinux. ...

  6. 为什么 API 治理需要内部倡导

    API 治理旨在帮助人们通过 API 实现最大价值.但是,只有了解 API 是什么以及 API 的重要性,并且认识到 API 治理是在帮助他们而不是监管他们,才能实现这一目标.这就是为什么在任何 AP ...

  7. 定义一个函数,传入一个字典和一个元组,将字典的值(key不变)和元组的值交换,返回交换后的字典和元组

    知识点:zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表. li=[3,4,5] t=(7,8,9) print(list(zip(li,t ...

  8. MindSponge分子动力学模拟——软件架构(2023.08)

    技术背景 在前面一篇文章中,我们介绍了MindSponge的两种不同的安装与使用方法,让大家能够上手使用.这篇文章主要讲解MindSponge的软件架构,并且协同mindscience仓库讲解一下二者 ...

  9. springboot集成seata1.5.2+nacos2.1.1

    一.前言 Seata出现前,大部分公司使用的都是TCC或者MQ(RocketMq)等来解决分布式事务的问题,TCC代码编写复杂,每个业务均需要实现三个入口,侵入性强,RocketMQ保证的是最终一致性 ...

  10. 响应式编程——初识 Flux 和 Mono

    by emanjusaka from ​ https://www.emanjusaka.top/archives/4 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 Reactor ...