python3绘制股票K线图的那些坑【二】pyQtgraph绘制精美股票K线图---之对数坐标(log Y)呈现(转载)

本文探讨使用PyQtgraph库绘制K线图时,普通坐标系与对数坐标系对图形表现的影响。通过对比实验,展示对数坐标下K线图的正确性和对视觉分析的益处。

之前尝试使用mplfinance库做了K线图的呈现。感觉不是很理想,又找到了这个pyQtgraph库,网络上已经有一些人做了K线图的呈现,但是并不满意。主要是对于经常看盘的人来说,图形呈现的特征很重要,这就不得不说一下普通坐标系和对数坐标系的影响了!

    大多数现有的看盘软件呢,都有坐标设置,右键Y轴坐标尺的位置,就可以选择了。通常有普通坐标和对数坐标之分,我一直使用对数坐标,这个很关键。在对数坐标下,其实股票或者期货的K线图,长期的趋势才是正确的,如果用普通坐标,那么其实会影响到我们的大脑发现价格走势运动中的规律。关键问题在什么地方呢?

    关键问题在对数坐标下图形,没有被扭曲,看盘的人都明白,人脑是这个世界上最强的学习系统和分析系统,尤其是图形分析方面至今任何计算机所不能及。而普通坐标系的情况下,看盘软件直接用价格数据去画K线图,会导致什么呢?同样是涨10%的幅度,普通坐标系中,同一副图里,价格低的区间里和价格高的区间里,K线的长度是不同的。这就违背了我们看盘的基本原则,看盘的核心目的是从价格走势的图中发现规律,而K线的长短,对我们视觉的直观直觉就是涨落的幅度,普通坐标系会导致低价区涨落的幅度看上去小,而高价区的涨落幅度看上去大!但是对数坐标则不同,对数坐标,将价格取e为底的对数,然后再绘图,它确保了整个图形上,涨跌幅度一致的K线,其长度是一致的。同样涨跌10%,在低价区的K线大小和高价区的K线大小一致,这样不会给我们的大脑传递错误信号,更有利于我们的大脑来分析图形中可能蕴含的规律。

    废话不多说。先上代码!这组代码着实折腾了好长时间!Candlestick也就是俗称的日本蜡烛图,是pyQtgraph里的自定义图形呈现实例。不清楚根本的原因,只是发现如果使用setLogMode设置y轴为log对数坐标系,对自定义图形不起作用。这个后面再研究吧。依据官方示例,修改了一个对比效果,大家可以看看差别。

import pyqtgraph as pg
from pyqtgraph import QtCore, QtGui
import numpy

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):
    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):
    return QtCore.QRectF(self.picture.boundingRect())

data = [ ## 数据对应关系 (time, open, close, min, max).
(1., 10, 13, 5, 15),
(2., 13, 17, 9, 20),
(3., 17, 14, 11, 23),
(4., 14, 15, 5, 19),
(5., 15, 9, 8, 22),
(6., 9, 15, 8, 16),
(7., 1.0, 1.3, 0.5, 1.5),#这里把官方示例的数据缩小10倍,为的是能明显开出K线的差别
(8., 1.3, 1.7, 0.9, 2.0),
(9., 1.7, 1.4, 1.1, 2.3),
(10., 1.4, 1.5, 0.5, 1.9),
(11., 1.5, 0.9, 0.8, 2.2),
(12., 0.9, 1.5, 0.8, 1.6),
]
item = CandlestickItem(data) #原始数据,对应(0,0)幅图

npdata=numpy.array(data)
logYdata=numpy.log(npdata[:,1:])
logYdata=numpy.insert(logYdata,0,values=npdata[:,0],axis=1)
logYdata=list(map(tuple,logYdata))
item2 =CandlestickItem(logYdata) #把原始数据里Y轴相关的数据,全部预先用log对数化处理一下,对应(0,1)

item3= CandlestickItem(data) #原始数据,对应第三幅图(1,0)

item4 =CandlestickItem(logYdata) #验证一下,是不是setLogMode在自定义组件的时候,得自己去实现(1,1)

w=pg.GraphicsWindow()
w.setWindowTitle(‘pyqtgraph example: customGraphicsItem’)
plt = w.addPlot(0,0, title=“X轴/Y轴普通坐标系”)
plt.addItem(item)
plt.showGrid(True, True)

plt2 = w.addPlot(0,1, title=“Y轴数据Log对数化处理”)
plt2.addItem(item2)
plt2.showGrid(True, True)

plt3 = w.addPlot(1,0, title=“Y轴设置为对数坐标模式”)
plt3.addItem(item3)
plt3.showGrid(True, True)
plt3.setLogMode(False, True)

plt4 = w.addPlot(1,1, title=“数据和坐标系都是对数模式”)
plt4.addItem(item4)
plt4.showGrid(True, True)
plt4.setLogMode(False, True)

Start Qt event loop unless running in interactive mode or using pyside.

if name == ‘main’:
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, ‘PYQT_VERSION’):
QtGui.QApplication.instance().exec_()
看看效果吧!

先说明一下,也许看文章的朋友不太懂布局管理器,这里面4幅图,使用了布局管理器来布局,当前用的是默认的gridlayout,网格布局管理器。用(行号,列号)来描述图形组件的位置,在头脑中把整个界面想成n行,n列的几大块儿,我这里是2行2列一共4大块,行和列的编号都是从0开始,所以分别就是(0,0)到(1,1)了。如下图:

很明显可以看出来,由于K线图形是自定义的图形,所以单单设置setLogMode是没用的,图形不会发生变化。所以我估计还是需要再看看官方文档,自定义的图形组件里,估计要实现相关的logMode的方法,把数据对数化处理了才行。就像(0,1)和(1,1)。看到对数化后的效果了么?价格涨了10倍以后,和价格涨10倍以前,涨跌幅度相同的情况下,K线的大小是一样的!这点很重要。对看盘做分析,寻找规律的人来说至关重要!!

原文链接:https://blog.youkuaiyun.com/supperman_009/article/details/107450953?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-4.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-4.nonecase&request_id=5f209da8f769fa6e5f5d4593

在使用 `pyqtgraph` 的 `CandlestickItem` 绘制 K 线图时,可能会出现绘制异常的情况,例如 K 线图显示不完整、颜色错误、坐标轴不匹配、图形绘制错位等问题。这些问题通常源于数据格式、绘图逻辑或视图设置不当。以下是一些常见问题及其修复方案: ### 1. 数据格式不正确导致绘制异常 K 线图的数据通常包含时间、开盘价、收盘价、最低价和最高价字段。如果传入 `CandlestickItem` 的数据格式不正确,例如字段名错误或数据类型不一致,会导致绘图失败或显示异常。 **修复方案:** 确保数据格式与 `CandlestickItem` 类中定义的字段一致。例如,若类中期望字段为 `time`, `open`, `close`, `min`, `max`,则需确保传入的数据具有相同字段名,并且每个字段的数据类型为数值型(如 float 或 int)[^2]。 ```python import numpy as np # 示例数据 data = [ (0.0, 100.0, 105.0, 95.0, 110.0), (1.0, 105.0, 103.0, 100.0, 110.0), (2.0, 103.0, 108.0, 102.0, 112.0) ] data = np.array(data, dtype=[('time', float), ('open', float), ('close', float), ('min', float), ('max', float)]) ``` ### 2. 坐标轴范围未正确设置导致显示异常 如果未正确设置坐标轴范围,可能导致 K 线图部分区域被截断或无法正确显示。 **修复方案:** 在绘制完成后,手动设置视图的坐标轴范围,确保所有 K 线数据都在视图范围内显示[^1]。 ```python view_box = plot_widget.getViewBox() view_box.setRange(xRange=[0, len(data)], yRange=[min(data['min']), max(data['max'])]) ``` ### 3. 绘图项未正确添加到视图中导致不显示 如果 `CandlestickItem` 实例未正确添加到视图中,可能导致 K 线图无法显示。 **修复方案:** 确保将 `CandlestickItem` 实例通过 `addItem` 方法添加到绘图区域中[^1]。 ```python plot_widget.addItem(candlestick_item) ``` ### 4. 颜色填充逻辑错误导致颜色显示异常 在 `generatePicture` 方法中,若未正确设置画笔和画刷,可能导致 K 线图颜色显示错误。 **修复方案:** 在绘制每根 K 线时,确保根据开盘价与收盘价的关系设置正确的颜色。例如,当开盘价高于收盘价时使用红色,反之使用绿色[^2]。 ```python if open > close: p.setBrush(pg.mkBrush('r')) else: p.setBrush(pg.mkBrush('g')) ``` ### 5. 对数坐标绘制异常 若在对数坐标log Y)下绘制 K 线图,未对数据进行相应处理,可能导致图形绘制错位或崩溃。 **修复方案:** 在启用对数坐标时,确保所有价格数据为正值,并在视图设置中启用对数坐标模式。 ```python plot_widget.setLogMode(y=True) ``` ### 6. 数据更新后未触发重绘导致图形不更新 在动态更新数据时,若未调用重绘方法,可能导致图形显示旧数据。 **修复方案:** 在更新数据后,调用 `update` 方法触发重绘[^1]。 ```python candlestick_item.update() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值