引言:当我们需要绘制时间序列不连续的OHLC(Open,High,Low,Close)折线图时,使用pandas的plot函数就会将两个时间链接在一起,形成一段长长的直线。 So Ugly! Follow this:
如何解决这个问题呢?
加载数据
从文件AU1806中读取二进制数据,转为pandas.DataFrame
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
pd.set_option('display.expand_frame_repr',False)
df=pd.read_pickle('AU1806')
rng_date = df.index
df = df.reset_index()
数据一览
定义映射函数
我们按照:’year’,’month’,’day’,’hour’,’minute’,’second’ 频率生成等间隔 frequency 时间列,并以此分组排序,取每一组的最后一项的index值和frequency值,保存在列表。
from collections import OrderedDict
def tick_category(frequency, step):
'''
根据频率和频数获取刻度的时间轴
frequency 可取值: 'year','month','day','hour','minute','second'
'''
if frequency=='year':
df['frequency'] = rng_date.strftime('%Y')
elif frequency=='month':
df['frequency'] = rng_date.strftime('%Y-%m')
elif frequency=='day':
df['frequency'] = rng_date.strftime('%Y-%m-%d')
elif frequency=='hour':
df['frequency'] = rng_date.strftime('%Y-%m-%d %H')
elif frequency=='minute':
df['frequency'] = rng_date.strftime('%Y-%m-%d %H:%M')
elif frequency=='second':
df['frequency'] = rng_date.strftime('%Y-%m-%d %H:%M:%S')
else:
df['frequency'] = rng_date.strftime('%Y')
num_date = OrderedDict()
for item in df.groupby('frequency'):
num_date[item[1].index[-1]] = item[0]
nums = list(num_date.keys())[::step]
dates = list(num_date.values())[::step]
return num_date,nums,dates
plot轻松绘图
为了便于细致的控制界面,直接采用matplotlib绘图。
def show_plot(frequency, step, columns, tick_count=10):
num_date,nums,dates = tick_category(frequency, step)
end_pos = nums[tick_count] if tick_count<len(nums) else nums[-1]
data = df.loc[:,columns][:end_pos]
axes = data.plot()
axes.set_xticks(nums[:end_pos])
axes.set_xticklabels(dates[:end_pos],rotation=45)
plt.show()
效果预览:
show_plot('year',1, ['open', 'high','low','close'], tick_count=10)
show_plot('month',1, ['open'], tick_count=10)
你看懂是怎么计算的了吗?是不是很简单