使用matplotlib繪制k線圖(去掉空白日期)

之前研究過(guò)使用 matplotlib.finance 中的 candlestick_ohlc() 方法繪制k線圖,但是有個(gè)很無(wú)語(yǔ)的問(wèn)題,繪制出來(lái)的k線不是連續(xù)的——周末兩天沒(méi)有被去掉,因此總是留下一個(gè)空檔。更不要說(shuō)遇上春節(jié)這樣的節(jié)假日,k線將留下很大一段無(wú)用的空白。非常影響觀察k線走勢(shì)。

K-BLANK.png

google查詢了一陣,零零散散看到一些解決思路,某些代碼可用;另外一些不知是因?yàn)楫?dāng)時(shí)使用的開(kāi)源包和現(xiàn)在有所差異還是什么的,總之把大段代碼復(fù)制過(guò)來(lái)測(cè)試,得到的只是一堆報(bào)錯(cuò)信息。不過(guò),總歸解決思路還是明確了。

解決思路

由于candlestick_ohlc() 方法內(nèi)部是將一個(gè)連續(xù)的日期作為x軸的刻度送到matplotlib的繪圖引擎中的,如果不是采用修改 candlestick_ohlc() 的源碼,那么比較合理方法就是不要將日期數(shù)據(jù)送到 candlestick_ohlc() 方法中,并且重新自定義 x 軸的刻度。

股票數(shù)據(jù)重構(gòu)

matplotlib 官方給出的candlestick_ohlc() 的推薦使用方式是這樣:

mpf.candlestick_ochl(ax,data_mat,colordown='#53c156', colorup='#ff1717',width=0.3,alpha=1)

其中 ax 是繪制圖形的 axis 對(duì)象,data_mat 是所有的股票數(shù)據(jù)。股票數(shù)據(jù)是一個(gè)二維矩陣,每一行都是按照 date,open,close,high,low,volume 的順序排列的。這里 date 的值并不是 string,也不是 datetime,而是 pandas.TimeStamp。其實(shí)TimeStamp就是一個(gè)整型數(shù)字,類(lèi)似于unix 系統(tǒng)中的 timestamp。

所以在構(gòu)建股票數(shù)據(jù)時(shí),date 這個(gè)位置我們可以將它賦值為從0開(kāi)始的連續(xù)自然數(shù),這樣 candlestick_ochl() 方法繪圖時(shí),就不會(huì)把 date 轉(zhuǎn)化為一個(gè)連續(xù)的日期(還包含周末那種)。所以,重構(gòu)后的股票數(shù)據(jù)大致應(yīng)該是這樣:

[
  (0, 16.14, 16.24, 16.36, 16.14, 481999.28),
   (1, 16.24, 16.32, 16.38, 16.2, 424100.84), 
  (2, 16.32, 16.33, 16.39, 16.32, 276957.25), 
  (3, 16.3, 16.17, 16.38, 16.16, 277753.09)
]

每一行都是一個(gè)元組,元組里分別是 date, open, close, high, close 數(shù)據(jù)。

這樣一來(lái),繪制的圖形就變成了:

K-BLANK2.png

可以看到,k線圖形變得連貫了。但是x軸的刻度卻變成了自然數(shù),而非日期。所以,x 軸的刻度需要單獨(dú)處理一下。

x軸刻度設(shè)定

假定所有的日期字符串都在 data['date'] 中,簡(jiǎn)單把所有日期數(shù)據(jù)甩給matplotlib,x軸的刻度就會(huì)密密麻麻的擠在一起。

ax.set_xticks(range(len(date_tickers)))
ax.set_xticklabels(date_tickers)
K-BLANK3.png

那么如何讓 matplotlib 在繪圖時(shí)只保留主要刻度呢?

如果只是這樣:

ax.set_xticklabels(date_tickers)
K-BLANK4.png

乍一看,問(wèn)題解決了!但是仔細(xì)一看,刻度不對(duì)!最后一個(gè)日期居然還是 2017-1-12 日,而k線已經(jīng)是60天的數(shù)據(jù)了。

正確的姿勢(shì)應(yīng)該是用:

import matplotlib.ticker as ticker

# 先設(shè)定一個(gè)日期轉(zhuǎn)換方法
def format_date(x,pos=None):
    # 由于前面股票數(shù)據(jù)在 date 這個(gè)位置傳入的都是int
    # 因此 x=0,1,2,...
    # date_tickers 是所有日期的字符串形式列表
    if x<0 or x>len(date_tickers)-1:
        return ''
    return date_tickers[int(x)]

# 用 set_major_formatter() 方法來(lái)修改主刻度的文字格式化方式
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))

這樣一來(lái),就變成我想要的效果了:

K-BLANK5.png

但是,還有一點(diǎn)不滿意,matplotlib自動(dòng)生成的主刻度的間距,我認(rèn)為太寬了。那么,我還可以用:

ax.xaxis.set_major_locator(ticker.MultipleLocator(6))

來(lái)強(qiáng)制指定每隔6個(gè)刻度,設(shè)定一個(gè)主刻度。圖形效果就變成了這樣:

K-BLANK6.png

完整的代碼

import matplotlib.pyplot as plt
import matplotlib.finance as mpf
import numpy as np
import pandas as pd
from matplotlib.pylab import date2num
import matplotlib.ticker as ticker
import time

data=pd.read_csv(u'assets/興業(yè)銀行.csv',usecols=['date','open','close','high','low','volume'])
data[data['volume']==0]=np.nan
data=data.dropna()
data.sort_values(by='date',ascending=True,inplace=True)
# 原始的csv 讀入進(jìn)來(lái) DataFrame 的 columns 順序不符合candlestick_ochl 要求的順序
# columns 的順序一定是 date, open, close, high, low, volume
# 這樣才符合 candlestick_ochl 繪圖要求的數(shù)據(jù)結(jié)構(gòu)
# 下面這個(gè)是改變列順序最優(yōu)雅的方法
data=data[['date','open','close','high','low','volume']]
data=data.head(62)

# 生成橫軸的刻度名字
date_tickers=data.date.values

weekday_quotes=[tuple([i]+list(quote[1:])) for i,quote in enumerate(data.values)]
# print weekday_quotes

fig,ax=plt.subplots(figsize=(1200/72,480/72))

def format_date(x,pos=None):
    if x<0 or x>len(date_tickers)-1:
        return ''
    return date_tickers[int(x)]

ax.xaxis.set_major_locator(ticker.MultipleLocator(6))
ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))
ax.grid(True)
# fig.autofmt_xdate()

mpf.candlestick_ochl(ax,weekday_quotes,colordown='#53c156', colorup='#ff1717',width=0.2)
plt.show()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容