import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
plt.style.use('ggplot')
# plt.rcParams.update(plt.rcParamsDefault)
from mpl_finance import candlestick_ohlc,candlestick2_ohlc
# import mplfinance as mpf
import pymysql
plt.rcParams["font.sans-serif"]=["simhei"]
plt.rcParams["axes.unicode_minus"]=False
pd.set_option("display.float_format",lambda x:'%.4f'%x)
code="000732.SZ"#绘制的股票代码
start_date=20200724#绘制的日期范围
end_date=20200804
conn=pymysql.connect(host="localhost",user="Bran",password='1234',port=3306,database="demo")
sql="select trade_date,open,high,low,close,vol from stock_daily_basic " \
"where ts_code='{}' and trade_date between '{}' and '{}';".format(code,start_date,end_date)
df=pd.read_sql(sql,conn)
df.trade_date=pd.to_datetime(df.trade_date,format='%Y-%m-%d').dt.date
# print(df.head())
conn.close()
# print(df.info())
###绘制K线图
fig=plt.figure()
ax_main=plt.subplot2grid(shape=(6,1),loc=(0,0),rowspan=4)
ax_vol=plt.subplot2grid(shape=(6,1),loc=(4,0),rowspan=2,sharex=ax_main)
candlestick2_ohlc(ax_main,opens=df.open,closes=df.close,lows=df.low,highs=df.high
,width=0.2,colorup='red',colordown='green')
ax_main.get_xaxis().set_visible(False) #隐藏ax_main的的X坐标轴
argmin=df.low.argmin()
argmax=df.high.argmax()
ax_main.text(argmin,df.low[argmin],"
ax_main.text(argmax,df.high[argmax],"
###绘制均线
ax_main.plot(np.arange(len(df.trade_date))
,df.close.rolling(window=10).mean()
,color="steelblue",label='10天均线',linewidth=0.5)
ax_main.plot(np.arange(len(df.trade_date))
,df.close.rolling(window=30).mean()
,color="orange",label='30天均线',linewidth=0.5)
ax_main.plot(np.arange(len(df.trade_date))
,df.close.rolling(window=180).mean()
,color="black",label='180天均线',linewidth=0.5)
ax_main.legend(loc=9,ncol=3,fontsize=8)
for index, row in df.iterrows():
if row.close >= row.open:
ax_vol.bar(x=index,height=row.vol,color='red')
else:
ax_vol.bar(x=index,height=row.vol,color='green')
def format_date(x,pos):
#x为坐标轴的值np.arange(len(df.trade_date)),pos为位置position
if x<0 or x>len(date_tickers)-1:
return ''
else:
return date_tickers[int(x)]
date_tickers = df.trade_date.values
# ax_vol.xaxis_date()#设置日期格式的坐标轴
import matplotlib.ticker as ticker
ax_vol.set_xticklabels(df.trade_date,rotation=15,ha='right')#设置横坐标标签为日期,并使横坐标旋转
argmax_vol=df.vol.argmax()
ax_vol.text(argmax_vol,df.vol[argmax_vol],"
# print(df.head(10))
ax_vol.ticklabel_format()
ax_vol.set_ylabel("成交量")
# ax_vol.set_xticks(range(0,len(df.trade_date.unique()),200))
ax_main.set_ylabel("价格")
# ax_main.get_xaxis().set_visible(False) #隐藏ax_mainde的X坐标轴
ax_main.set_title("股票{}的K线图".format(code))
ax_vol.xaxis.set_major_locator(ticker.MultipleLocator(np.ceil(len(df)/10)))
ax_vol.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))#调用函数显示X轴格式
ax_vol.yaxis.get_major_formatter().set_powerlimits((0,5)) #控制坐标轴显示位数,相当于禁止科学计数法
# ax_vol.autoscale_view()
# ax_main.spines['top'].set_visible(True)
# ax_main.spines['right'].set_visible(True)
# ax_main.spines['bottom'].set_visible(True)
# ax_main.spines['left'].set_visible(True)
# ax_main.grid(True)
plt.show()
'''由于matplotlib会将日期数据理解为连续数据,而连续数据之间的间距是有意义的,所以非交易日即使没有数据,在坐标轴上还是会体现出来。连续多少个非交易日,在坐标轴上就对应了多少个格子,但这些格子上方并没有相应的K线图。
可以给横坐标(日期)传入连续的、固定间距的数据,先保证K线图的绘制是连续的;然后生成一个保存有正确日期数据的列表,接下来,根据坐标轴上的数据取对应的正确的日期,并替换为坐标轴上的标签即可。
上边format_date函数就是这个作用。由于前边我们给dates列生成了从0开始的序列连续数据,因此我们可以直接把它当作索引,从真正的日期列表里去取对应的数据。在这里我们要使用matplotlib.ticker.FuncFormattter()方法,它允许我们指定一个格式化坐标轴标签的函数,在这个函数里,我们需要接受坐标轴的值以及位置,并返回自定义的标签。
'''