PyQt绘制股票K线多图Y坐标对齐

3 篇文章 0 订阅

在做股票的K线图与成交量图的时候,成交量数字宽度与K线数字宽度不一致,会导致Y坐标位置bu不在同一个位置上, 如下图:
在这里插入图片描述pyqtgraph没有直接调整的Y轴位置。但是pyqtgraph本身就是使用QGrapics框架实现的,因此直接查看pyqtgraph源代码。

在这里插入图片描述
负责处理坐标轴的为AxisItem类, 再查看内部实现,发现存在两个接口setHeight和setWidth两个接口, 如下图:
在这里插入图片描述意思是设置这两个接口则可以改变坐标宽度。因此可以使用此方法改变宽度来对齐Y轴。

    def y_axis_max_width(self) -> int:
        font = self.font()
        fm = QFontMetrics(font)
        y_max = self._data['high'].max()
        y_min = self._data['low'].min()
        y_max_len = fm.width("%.02f" % y_max)
        y_min_len = fm.width("%.02f" % y_min)
        max_len = max(y_max_len, y_min_len)
        return max_len

    def set_y_axis_width(self, width):
        self.y_axis.setWidth(width)
        self._pw.setAxisItems({'left': self.y_axis})
        self.update()

    def update_data(self, data):
        self._k_widget.update_data(data)
        self._line_widget.update_data(data)
        self._vol_widget.update_data(data)
        self._k_widget.view_box().setXLink(self._vol_widget.view_box())
        self._line_widget.view_box().setXLink(self._vol_widget.view_box())

        k_y_width = self._k_widget.y_axis_max_width()
        l_y_width = self._line_widget.y_axis_max_width()
        v_y_width = self._vol_widget.y_axis_max_width()
        max_width = max([k_y_width, l_y_width, v_y_width])
        if k_y_width <= max_width:
            self._k_widget.set_y_axis_width(max_width)

        if l_y_width <= max_width:
            self._line_widget.set_y_axis_width(max_width)

        if v_y_width <= max_width:
            self._vol_widget.set_y_axis_width(max_width)

根据数据查询最大数据和最小数据,然后获取最大像素作为宽度,然后在更新数据的时候设置最大的宽度即可。
具体结果如下:

在这里插入图片描述

以下是使用PyQt5绘制K线图的示例代码: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget from PyQt5.QtChart import QChart, QChartView, QCandlestickSeries, QCandlestickSet from PyQt5.QtCore import Qt, QPointF, QRectF from PyQt5.QtGui import QPainter, QColor class KLineChart(QChartView): def __init__(self, data): super().__init__() self.chart = QChart() self.chart.legend().hide() self.chart.setBackgroundRoundness(0) self.chart.setAnimationOptions(QChart.NoAnimation) self.chart.createDefaultAxes() self.chart.axisX().setGridLineVisible(False) self.chart.axisY().setGridLineVisible(False) self.chart.axisX().setVisible(False) self.chart.axisY().setVisible(False) self.chart.axisX().setLabelsVisible(False) self.chart.axisY().setLabelsVisible(False) self.chart.axisX().setRange(0, len(data)) self.chart.axisY().setRange(min(data) * 0.95, max(data) * 1.05) series = QCandlestickSeries() for i in range(len(data)): candlestick_set = QCandlestickSet(data[i][0], data[i][1], data[i][2], data[i][3]) series.append(candlestick_set) self.chart.addSeries(series) self.setChart(self.chart) self.setRenderHint(QPainter.Antialiasing) self.setMouseTracking(True) def mouseMoveEvent(self, event): pos = event.pos() chart_pos = self.chart.mapToValue(pos) x = int(chart_pos.x()) y = chart_pos.y() self.chart.setTitle(f"K线图 - 当前位置:({x}, {y})") super().mouseMoveEvent(event) class MainWindow(QMainWindow): def __init__(self, data): super().__init__() self.setWindowTitle("K线图") self.resize(800, 600) central_widget = QWidget() layout = QVBoxLayout(central_widget) chart_view = KLineChart(data) layout.addWidget(chart_view) self.setCentralWidget(central_widget) if __name__ == "__main__": app = QApplication([]) data = [[100, 120, 80, 110], [110, 130, 90, 120], [120, 140, 100, 130], [130, 150, 110, 140]] window = MainWindow(data) window.show() app.exec_() ``` 这段代码使用了PyQt5的QChart和QCandlestickSeries类来绘制K线图。首先创建一个继承自QChartView的KLineChart类,然后在该类中创建一个QChart对象,并设置一些基本的样式和属性。接着,创建一个QCandlestickSeries对象,并根据提供的数据创建QCandlestickSet对象,并将其添加到QCandlestickSeries中。最后,将QCandlestickSeries添加到QChart中,并将QChart设置为KLineChart的图表。最后,创建一个继承自QMainWindow的MainWindow类,将KLineChart添加到布局中,并将布局设置为MainWindow的中心窗口部件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值