在大数据时代对数据按自己理解的进行可视化是非常关键的一部。我们以科大讯飞这一股票从14-11至17-11的数据进行可视化。我们还是以最简单的均线系统规律来确立简单的买卖点。版本python3。经历的步骤有:
1、提取数据;
2、解析数据,得到我们想要的数据;
3、对数据进行一定处理,便于可视化;
4、可视化;以下是代码:
# !/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys
import importlib
importlib.reload(sys)
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
def rowIndex(row):
"""添加需要的标记和标记位置"""
global plt
if row.signal > 0:
#标图示annotate
plt.annotate(u'b', xy=(row.date_o, row.signal), #xy表示被标注的位置
arrowprops=dict(facecolor='red', shrink=0.05))
if row.signal < 0:
plt.annotate(u's', xy=(row.date_o, row.signal))
if __name__ == '__main__':
#用lambda表达式将日期转换为字符格式
daterparse1 = lambda dates: pd.datetime.strptime(dates, "%Y-%m-%d")
#以特定格式和方式读取csv文件,pandas读取文件成为DataFrame对象或者Series对象
s_list = pd.read_csv('kd.csv', skiprows=0, encoding='utf-8',
index_col='date', parse_dates=True,
date_parser=daterparse1)
s_list['date_o'] = s_list.index #将DataFrame对象(本身就是字典)的索引存为 原日期的字典
s_list['ma_sub'] = s_list['ma5'] - s_list['ma20']
s_list['diff'] = np.sign(s_list['ma_sub']) #返回数组中的正负号,分别用1和-1表示
#shift为对齐操作
s_list['signal'] = np.sign(s_list['diff'] - s_list['diff'].shift(1))
s_list['signal'].plot(ylim=(-2, 2))
(s_list['close']/40).plot(ylim=(-2, 2))
s_list.apply(rowIndex, axis=1) #对DataFrame对象的行(axis=1)使用apply方法#返回行索引对应的Series对象
plt.legend(loc='upper right') #设置图例显示的位置
# plt.legend(loc=4) #upper right/left=1/2;lower left/right=3/4
plt.grid(b=True)
plt.title(u'Ma5--Ma20 to When Buy Or Sell', fontsize=18)
plt.show()
# plt.savefig('002230_mod.png', bbox_inches='tight')
代码解析:
1、需要用到的包,sys,matplotlib,pandas,numpy;
2、提取数据,我们用到的是csv格式数据,相应代码的功能在代码中已注释,首先以自定义方式读取数据,我们需要用到日期,收盘价,5日平均及20日平均价格;其中index_col关键字为指定以哪列数据为索引构建DataFrame数据;我们首先看看数据是什么样的:
对其提取之前先要对日期格式做一个调整;lambda可实现这一功能。parse_dates是对时间序列进行解析(为真);data_parser为解析日期的函数——有一个默认函数,但使用我们自己定义的函数;
3、对数据进行一系列处理,提取日期数据;求出均线差值:得出变化范围的标志;得出标记信号;限制绘图数据范围,避免溢出看不出趋势。
4、定义标记函数:用annotate函数实现按预期指定标记——标记符号,位置,箭头颜色和大小;按照行的信号大小来标记;大于0,标为买,小余0,标为卖;
5、可视化,利用定义的信号及收盘价、日期来绘制图表。以下是输出结果:
投资时点是一个极其重要的参考指标,为使买卖信号更清晰,便于提示我们什么时候进行买卖,我们可以把出现转机的时点作为文本,标在图上。
# !/usr/bin/env python
# -*- encoding:utf-8 -*-
import sys
import importlib
#importlib.reload(sys)
#Python3不同,使用上述语句替代,但不建议使用
#sys.setdefaultencoding('utf-8')
import matplotlib as mpl
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
#交错标注日期的转换标志
cn = 1
cnb = 1
def rowIndex(row):
"""根据指示绘制买卖信号的标志"""
global plt, cn, cnb
#交错标注日期的位置常数
buyt = 0.5
buyb = 0.5
if row.signal > 0:
#xy表示被注释的位置坐标
plt.annotate(u'B', xy=(row.date_o, row.signal),
arrowprops=dict(facecolor='red', shrink=0.05))
if cn == 1:
buyt = 1
cn = -1
else:
buyt = 0.5
cn = 1
plt.annotate(str(row.date_o).replace("-", "")[2:8], #日期字符化、替代、切片
xytext=(row.date_o, row.signal + buyt), #文本标注的位置
xy = (row.date_o, row.signal + 0.5), #指示标志的位置
arrowprops=dict(facecolor='red', shrink=0.5))
if row.signal < 0:
plt.annotate(u'S', xy=(row.date_o, row.signal))
if cnb == 1:
buyb = 1
cnb = -1
else:
buyb = 0.5
cnb = 1
plt.annotate(str(row.date_o).replace("-", "")[2:8],
xytext = (row.date_o, row.signal - buyb),
xy = (row.date_o, row.signal + 0.5),
arrowprops=dict(facecolor='red', shrink=0.5))
if __name__ =="__main__":
mpl.rcParams['font.sans-serif'] = ['Arial Unicode MS'] #正常显示中文标签
mpl.rcParams['axes.unicode_minus'] = False #正常显示负号
dateparse1 = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%d')
s_list = pd.read_csv("kd.csv", skiprows=0, encoding='utf-8',
index_col='date', parse_dates=True,
date_parser=dateparse1)
s_list['date_o'] = s_list.index
s_list['ma_sub'] = s_list['ma5'] - s_list['ma20']
s_list['diff'] = np.sign(s_list['ma_sub'])
s_list['signal'] = np.sign(s_list['diff'] - s_list['diff'].shift(1))
s_list['signal'].plot(ylim=(-2, 2))
(s_list['close']/40).plot(ylim=(-2, 2))
s_list.apply(rowIndex, axis=1)
plt.legend(loc='upper right')
plt.grid(b=True)
#打开matplotlib查看器查看图形
plt.show()
其中精妙之处在于,使用一个转换标志来交错的在图上标示提示信息,避免重叠,包括距离转换。以下是结果:
注意的是:
1、提示标志和提示信息是两块图层内容,需要分别绘制;
2、绘制提示信息时,需要用到条件语句进行限制,并随之变更转换标志,将提示信息交错绘制;
3、row在python中是一关键字,可以直接应用于对数据的相关处理(定义函数),调用函数时,程序自动按行查找,不需要传递实参。
要显示汉字,请参考!c12-4.