PyQt5 绘制柱状图(QPainter)

本文介绍如何使用PyQt5中的QPainter组件绘制柱状图。通过详细代码示例,讲解了如何设置坐标轴、计算像素点以及绘制不同样式的柱状图。此外,还展示了如何使用不同的画刷样式来区分不同的数据系列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PyQt5 绘制柱状图(QPainter)

我们使用Qpainter根据像素点绘制,像素点的计算与数学中的坐标轴类似但也有不同的地方。最主要的是它的原点坐标不在左下方而是在右上方,如图在这里插入图片描述

# pointy - end_Pox 表示柱状图在Y方向使用了多少像素点,num_start - num_Spacing 表示柱状图
# 数据的最大范围 两者相除得出每个刻度对应几个像素点
every_pox = (pointy - end_Pox) / (num_start - num_Spacing)
# 获取数值并计算出需要的像素 由于Y的坐标是从上往下算的我们可以用柱状图中的原点像素(pointy)减去
# 计算出来的像素
pointy - Y[i][3] * every_pox
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys


class MainWindows(QWidget):
    def __init__(self):
        super(MainWindows, self).__init__()
        self.resize(700,500)

    def paintEvent(self, QPaintEvent):
        X = [1, 2, 3, 4, 5, 6]
        Y = [[141, 400, 700, 460], [120, 50, 340, 55], [141, 400, 700, 460], [120, 50, 340, 55], [120, 50, 340, 55],
             [141, 400, 700, 460]]


        painter = QPainter()
        painter.begin(self)
        painter.setPen(Qt.NoPen)
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen(Qt.black, 2, Qt.SolidLine)
        painter.setPen(pen)
        pointx = 35
        pointy = self.height() - 50

        width = self.width() - 150 - pointx
        height = self.height()
        # X轴
        painter.drawLine(pointx, pointy, width + pointx, pointy)
        # Y轴
        painter.drawLine(pointx, pointy - height, pointx, pointy)

        X_Spacing = width / len(X)
        X_little_Spacing = width / len(X) / (len(Y[1]) + 1)

        Y_Spacing = height / len(Y)

        pen = QPen(Qt.red, 5, Qt.SolidLine)
        painter.setPen(pen)
        X_start = X_little_Spacing * 3 + 35
        X_pox = []
        for i in range(len(X)):
            painter.drawPoint(X_start - X_little_Spacing * 2, pointy)
            painter.drawPoint(X_start - X_little_Spacing, pointy)
            painter.drawPoint(X_start, pointy)
            painter.drawPoint(X_start + X_little_Spacing * 2, pointy)
            painter.drawPoint(X_start + X_little_Spacing, pointy)
            painter.drawText(X_start - 15, pointy + 20, str(X[i]))
            X_pox.append(X_start)

            X_start = X_start + X_Spacing
        # print(X_pox)
        Y_max = 0
        for i in range(len(Y)):
            if Y_max < max(Y[i]):
                Y_max = max(Y[i])
        num_Spacing = int(Y_max / (len(Y) - 1)) + 1

        num_start = 0
        Y_start_pox = 0
        end_Pox = 0
        for i in range(len(Y)):
            painter.drawPoint(35, pointy - Y_start_pox)
            end_Pox = pointy - Y_start_pox
            painter.drawText(pointx - 30, pointy - Y_start_pox + 5, str(num_start))
            Y_start_pox = Y_start_pox + Y_Spacing
            num_start = num_start + num_Spacing
        every_pox = (pointy - end_Pox) / (num_start - num_Spacing)

        pen = QPen(Qt.black, 1, Qt.SolidLine)
        painter.setPen(pen)
        print(X_pox)
        for i in range(len(X)):
            brush = QBrush(Qt.Dense1Pattern)
            painter.setBrush(brush)
            painter.drawText(X_pox[i] - X_little_Spacing * 2, pointy - Y[i][0] * every_pox - 5, str(Y[i][0]))
            painter.drawRect(X_pox[i] - X_little_Spacing * 2, pointy - Y[i][0] * every_pox, X_little_Spacing,
                             Y[i][0] * every_pox)
            brush = QBrush(Qt.DiagCrossPattern)
            painter.setBrush(brush)
            painter.drawText(X_pox[i] - X_little_Spacing, pointy - Y[i][1] * every_pox - 5, str(Y[i][1]))
            painter.drawRect(X_pox[i] - X_little_Spacing, pointy - Y[i][1] * every_pox, X_little_Spacing,
                             Y[i][1] * every_pox)
            brush = QBrush(Qt.Dense2Pattern)
            painter.setBrush(brush)
            painter.drawText(X_pox[i], pointy - Y[i][2] * every_pox - 5, str(Y[i][2]))
            painter.drawRect(X_pox[i], pointy - Y[i][2] * every_pox, X_little_Spacing, Y[i][2] * every_pox)
            brush = QBrush(Qt.Dense3Pattern)
            painter.setBrush(brush)
            painter.drawText(X_pox[i] + X_little_Spacing, pointy - Y[i][3] * every_pox - 5, str(Y[i][3]))
            painter.drawRect(X_pox[i] + X_little_Spacing, pointy - Y[i][3] * every_pox, X_little_Spacing,
                             Y[i][3] * every_pox)

        brush = QBrush(Qt.Dense1Pattern)
        painter.setBrush(brush)
        painter.drawRect(self.width() - 140, 10, 50, 20)
        painter.drawText(self.width() - 80, 25, "Dense1Pattern")

        brush = QBrush(Qt.DiagCrossPattern)
        painter.setBrush(brush)
        painter.drawRect(self.width() - 140, 35, 50, 20)
        painter.drawText(self.width() - 80, 50, "DiagCrossPattern")

        brush = QBrush(Qt.Dense2Pattern)
        painter.setBrush(brush)
        painter.drawRect(self.width() - 140, 60, 50, 20)
        painter.drawText(self.width() - 80, 75, "Dense2Pattern")

        brush = QBrush(Qt.Dense3Pattern)
        painter.setBrush(brush)
        painter.drawRect(self.width() - 140, 85, 50, 20)
        painter.drawText(self.width() - 80, 100, "Dense3Pattern")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = MainWindows()
    demo.show()
    sys.exit(app.exec_())

效果图如下:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值