python用mpl_finance中的candlestick_ohlc画分时图

matplotlib.finance独立出来成为mpl_finance,而mpl_finance中的candlestick_ochl和candlestick_ohlc一般用来画股票的K线图。我需要分析分时图,也就是一分钟的行情,这个时候就不能直接用candlestick_ochl函数,因为candlestick_ochl中x轴最小的单位是日期,不是分钟。

经过对mpl_finance的源代码进行分析,问题在于matplotlib的date2num将日期转换为浮点数,浮点数的整数部分表示日期,小数部分代表小时和分钟。比如下面4个时间段是连续的分钟。

时间    date2num之后    乘以1440
2018/09/17-21:34    736954.8986    1061215054
2018/09/17-21:35    736954.8993    1061215055
2018/09/17-21:36    736954.9000    1061215056
2018/09/17-21:37    736954.9007    1061215057
可以看出date2num函数计算之后,4个时间的整数部分都是736954,导致在X轴上这4个时间段都重叠在一起,无法区分了。要达到的效果是每一个分钟也能成为一个整数,这样就可以显示出来了。那么一天是24小时,每小时60分钟,那么一天就是1440分钟,将date2num计算的浮点数乘以1440就可以将每一分钟转为整数,那么就可以在x轴上。

最后还需要对x轴格式化,因为自己对x轴进行了处理(乘以1440),采用默认的格式化是乱码。需要自定义x轴的格式化函数。

import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
import matplotlib.dates as dates
import mpl_finance as mpf
from matplotlib.ticker import Formatter
import numpy as np
 
 
dfcvs = DataFrame([
    ["2018/09/17-21:34", 3646, 3650,3644,3650],
    ["2018/09/17-21:35", 3650, 3650,3648,3648],
    ["2018/09/17-21:36", 3650, 3650,3648,3650],
    ["2018/09/17-21:37", 3652, 3654,3648,3652]
])
 
dfcvs.columns = ['时间','开盘','最高','最低','收盘']
dfcvs['时间']=pd.to_datetime(dfcvs['时间'],format="%Y/%m/%d-%H:%M")
 
#matplotlib的date2num将日期转换为浮点数,整数部分区分日期,小数区分小时和分钟
#因为小数太小了,需要将小时和分钟变成整数,需要乘以24(小时)×60(分钟)=1440,这样小时和分钟也能成为整数
#这样就可以一分钟就占一个位置
 
 
 
dfcvs['时间']=dfcvs['时间'].apply(lambda x:dates.date2num(x)*1440)
data_mat=dfcvs.as_matrix()
    
fig,ax=plt.subplots(figsize=(1200/72,480/72))
 
fig.subplots_adjust(bottom=0.1)   
mpf.candlestick_ohlc(ax,data_mat,colordown='#53c156', colorup='#ff1717',width=0.2,alpha=1)
 
#将x轴的浮点数格式化成日期小时分钟
#默认的x轴格式化是日期被dates.date2num之后的浮点数,因为在上面乘以了1440,所以默认是错误的
#只能自己将浮点数格式化为日期时间分钟
#参考https://matplotlib.org/examples/pylab_examples/date_index_formatter.html
class MyFormatter(Formatter):
            def __init__(self, dates, fmt='%Y%m%d %H:%M'):
                self.dates = dates
                self.fmt = fmt
    
            def __call__(self, x, pos=0):
                'Return the label for time x at position pos'
                ind = int(np.round(x))
                #ind就是x轴的刻度数值,不是日期的下标
 
                return dates.num2date( ind/1440).strftime(self.fmt)
        
formatter = MyFormatter(data_mat[:,0])
ax.xaxis.set_major_formatter(formatter)
 
for label in ax.get_xticklabels():
            label.set_rotation(90)
            label.set_horizontalalignment('right')
           
plt.show()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值