当前位置: 首页 > news >正文

PyQt6基础_pyqtgraph_k线图缩放

目录

前置:

代码

演示

视频


前置:

1 pyqtgraph默认的缩放功能经常让K线不消失在可视区域,与通达信等软件的缩放体验差别巨大

2 pyqtgraph的缩放策略是以鼠标所在位置为中心进行x轴和y轴的缩放。当鼠标所在位置偏离K线主体很远时,K线主体经常消失,或者K线显示不全

3 修改思想,不管放大还是缩小,计算缩放后K线主体的x轴y轴范围,将缩放后的可视区域设置为缩放后K线主体的x轴和y轴范围,这样就能保证可视区域内总是完整的K线图。

4 在 pyqtgraph 里面,鼠标滚轮事件wheelEvent有一个delta可以表征滚轮的向上和向下
向上,放大,delta大于1,显示的内容减少(显示的K线个数减少)
向下,缩小,delta小于1,显示的内容增多(显示的K线个数增多)
根据以上逻辑,重写pg.PlotWidget()里面的wheelEvent

代码

from PyQt6.QtCore import (
QSize
)
from PyQt6.QtWidgets import (
QApplication,
QMainWindow,
QVBoxLayout,
QWidget
)
import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import pandas as pd
import numpy as np


## Create a subclass of GraphicsObject.
## The only required methods are paint() and boundingRect()
## (see QGraphicsItem documentation)
class CandlestickItem(pg.GraphicsObject):
    def __init__(self, data):
        pg.GraphicsObject.__init__(self)
        self.data = data  ## data must have fields: time, open, close, min, max
        self.generatePicture()

    def generatePicture(self):
        ## pre-computing a QPicture object allows paint() to run much more quickly,
        ## rather than re-drawing the shapes every time.
        self.picture = QtGui.QPicture()
        p = QtGui.QPainter(self.picture)
        p.setPen(pg.mkPen('w'))
        w = (self.data[1][0] - self.data[0][0]) / 3.
        for (t, open, close, min, max) in self.data:
            p.drawLine(QtCore.QPointF(t, min), QtCore.QPointF(t, max))
            if open > close:
                p.setBrush(pg.mkBrush('r'))
            else:
                p.setBrush(pg.mkBrush('g'))
            p.drawRect(QtCore.QRectF(t - w, open, w * 2, close - open))
        p.end()

    def paint(self, p, *args):
        p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        ## boundingRect _must_ indicate the entire area that will be drawn on
        ## or else we will get artifacts and possibly crashing.
        ## (in this case, QPicture does all the work of computing the bouning rect for us)
        return QtCore.QRectF(self.picture.boundingRect())

class StrAxisItem(pg.AxisItem):
    def __init__(self,ticks,*args,**kwargs):
        pg.AxisItem.__init__(self,*args,**kwargs)
        self.x_values = [x[0] for x in ticks]
        self.x_strings = [x[1] for x in ticks]
        pass
    def tickStrings(self, values, scale, spacing):
        strings = []
        for v in values:
            vs = v*scale
            if vs in self.x_values:
                vstr = self.x_strings[self.x_values.index(vs)]
            else:
                vstr = ''
            strings.append(vstr)
        return strings

class KPlotWidget(pg.PlotWidget):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.df_data:pd.DataFrame = pd.DataFrame()
        pass
    def setDfData(self,data:pd.DataFrame):
        self.df_data = data
        pass
    def wheelEvent(self, ev):
        if len(self.df_data) <= 0:
            super().wheelEvent(ev)
        else:
            delta = ev.angleDelta().x()
            if delta == 0:
                delta = ev.angleDelta().y()

            s = 1.001 ** delta

            before_xmin, before_xmax = self.viewRange()[0]
            val_x = self.getViewBox().mapSceneToView(ev.position()).x()

            after_xmin = val_x - (val_x - before_xmin) // s
            after_xmax = val_x + (before_xmax - val_x) // s

            if after_xmin < 0:
                after_xmin = 0
            if after_xmax >= len(self.df_data):
                after_xmax = len(self.df_data) - 1

            df00 = self.df_data.loc[(self.df_data['a00'] >= after_xmin) & (self.df_data['a00'] <= after_xmax)].copy()
            after_ymin = df00['lowestPrice'].min()
            after_ymax = df00['highestPrice'].max()

            self.setXRange(after_xmin, after_xmax)
            self.setYRange(after_ymin, after_ymax)
            pass


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('pyqtgragh实例')
        self.setMinimumSize(QSize(800,600))

        self.pw = KPlotWidget()
        self.pw.setMouseEnabled(x=True,y=True)

        layout = QVBoxLayout()
        layout.addWidget(self.pw)
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)
        self.open_init()
        pass
    def open_init(self):
        df = pd.read_excel(r'E:/temp003/600584_adj.xlsx',engine='openpyxl')
        df = df.loc[df['turnoverValue']!=0].copy()
        df['a00'] = np.arange(0,len(df))
        data = df.loc[:,['a00','openPrice','closePrice','lowestPrice','highestPrice']].values

        item = CandlestickItem(data)
        # ticks = [(i,j) for i,j in zip(df['a00'].to_list(),df['tradeDate'].to_list())]
        # print(ticks)
        ticks = df.loc[:,['a00','tradeDate']].values
        horAxis = StrAxisItem(ticks=ticks,orientation='bottom')
        # text_item = pg.TextItem(angle=-45,
        #                         html='<div style="transform: rotate(-45deg)">X Axis Label</div>')  # 创建文本项并设置旋转角度
        # horAxis.setLabel(text=text_item, angle=0)
        self.pw.setAxisItems({'bottom':horAxis})
        self.pw.addItem(item)
        self.pw.setDfData(df)
        pass


if __name__ == '__main__':
    app = QApplication([])
    mw = MainWindow()
    mw.show()
    app.exec()
    pass

演示

视频

PyQt6基础_pyqtgraph_k线图缩放_哔哩哔哩_bilibili

相关文章:

  • 41、web前端开发之Vue3保姆教程(五 项目实战)
  • 足球比分分析页面可视化展示
  • ImportError: The ‘read_file‘ function requires the ‘pyogrio‘ or ‘fiona‘ package
  • 【深度学习与实战】3.1 逻辑回归模型
  • 网络相关基本概念
  • Rasa总体目录架构介绍
  • Python中如何用正则表达式精准匹配IP地址?
  • 常用环境部署(二十六)——Centos搭建MQTT服务端EMQX
  • 35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
  • OpenStack Yoga版安装笔记(十九)启动一个实例(Self-service networks)
  • mysql 重复读自己事务中可以看到新插入数据
  • JS里对于Map的简单介绍
  • 蓝桥杯简单题练习
  • win11 redis3.0下载和运行
  • 力扣面试150题--有效的数独
  • 【Android】Android 打包 Release 崩溃问题全解析:Lint 错误、混淆类丢失及解决方法大全
  • React 条件渲染
  • Agent2Agent协议学习资源大全:从理论到实践
  • 【Linux】单例模式及其在线程池中的应用
  • Spring Boot 集成 POI
  • app网站制作多少钱/seo推广系统
  • 做一个网站的基本步骤/网页设计模板
  • php网站开发心得/百度上海分公司地址
  • wordpress 新浪云/东莞网络优化排名
  • 独立站怎么推广/新十条优化措施
  • asp.net个人网站怎么做/微信销售平台