可视化神器Plotly玩转股票图
本文是可视化神器Plotly绘图的第7篇,讲解的是如何通过Plotly来绘制与股市相关的图形,比如基础K线图、OHLC图等。
温馨提示⚠️:**股市有风险,投资需谨慎,**这并不妨碍大家学习Plotly
的绘图技巧!
扩展阅读
Plotly的文章会形成连载系列,前面5篇的Plotly可视化文章分别是:
- 酷炫!36张图爱上高级可视化神器Plotly_Express
- Plotly玩转散点图
- Plotly玩转饼图
- Plotly玩转漏斗图
- Plotly玩转柱状图
- Plotly玩转气泡图
导入库
代码语言:javascript复制import pandas as pd
import numpy as np
# 两个接口
import plotly_express as px
import plotly.graph_objects as go
股市图
下面简单介绍下两种股市相关的图:
- K线图
- OHLC图
K线图
K线由开盘价、收盘价、最高价、最低价四个价位组成。开盘价低于收盘价称为阳线,反之叫阴线。
中间的矩形称为实体,实体以上细线叫上影线,实体以下细线叫下影线。
1、红色上涨:
2、绿色下跌
3、持平状态
根据K线的计算周期可将其分为:日K线、周K线、月K线、年K线
OHLC线图
摘录来自维基百科的一段介绍:
美国线**(英语:Open-High-Low-Close chart,OHLC chart),以竖立的线条表现股票价格的变化,可以呈现“开盘价、最高价、最低价、收盘价”,竖线呈现最高价和最低价间的价差间距,左侧横线代表开盘价,右侧横线代表收盘价
绘制OHLC图
绘图数据
在本文中很多图形都是基于Plotly中自带的一份关于苹果公司AAPL的股票数据绘制,先看看具体的数据长什么样子:利用pandas读取网站在线的csv文件
代码语言:javascript复制# 读取在线的csv文件
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
df.head() # 显示前5行数据
数据大小为:
代码语言:javascript复制df.shape
# 结果
(506,11)
所有的字段为:
代码语言:javascript复制df.columns
# 结果
Index(['Date', 'AAPL.Open', 'AAPL.High', 'AAPL.Low', 'AAPL.Close',
'AAPL.Volume', 'AAPL.Adjusted', 'dn', 'mavg', 'up', 'direction'],
dtype='object')
基础绘图
代码语言:javascript复制# The 'close' property is an array that may be specified as a tuple, list, numpy array, or pandas Series
fig = go.Figure(data=go.Ohlc(
x=df['Date'],
open=df['AAPL.Open'], # 字段数据必须是元组、列表、numpy数组、或者pandas的Series数据
high=df['AAPL.High'],
low=df['AAPL.Low'],
close=df['AAPL.Close']
))
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()
添加文本信息和备注
代码语言:javascript复制fig = go.Figure(data=go.Ohlc(
x=df['Date'], # 日期和四组数据
open=df['AAPL.Open'],
high=df['AAPL.High'],
low=df['AAPL.Low'],
close=df['AAPL.Close']
))
fig.update_layout(
title="苹果公司股票走势图", # 标题
yaxis_title="股票价格", # y轴名称
shapes = [dict( # 显示形状的位置和线宽等信息
x0='2015-06-01', x1='2016-05-13', # x的取值
y0=0, y1=1, # y的取值
xref='x', yref='paper',
line_width=2)],
annotations=[dict( # 备注信息
x='2015-06-01', y=0.05,
xref='x', yref='paper',
showarrow=False,
xanchor='left',
text='下降阶段')]
)
fig.show()
上图中添加了方框中的特选部分和备注
自定义颜色
上面的图形是Plotly自带的颜色:涨是红色,跌是绿色,下图中将涨变成了蓝色
代码语言:javascript复制fig = go.Figure(data=[go.Ohlc(
x=df['Date'], # 日期
open=df['AAPL.Open'], # 4组数据
high=df['AAPL.High'],
low=df['AAPL.Low'],
close=df['AAPL.Close'],
increasing_line_color= 'blue', # 上升趋势颜色
decreasing_line_color= 'green' # 下降趋势颜色
)])
fig.show()
具体日期的OHLC图
上面的图形都是连续型日期(基于月份)的OHLC图形,下面介绍的是如何绘制具体某些日期的OHLC图形
代码语言:javascript复制# 如何生成一个datetime时间对象
import plotly.graph_objects as go
from datetime import datetime
datetime(year=2013, month=10, day=10)
代码语言:javascript复制# 绘制的4份数据
open_data = [133.0, 133.3, 133.5, 133.0, 134.1]
high_data = [133.1, 133.3, 133.6, 133.2, 134.8]
low_data = [132.7, 132.7, 132.8, 132.6, 132.8]
close_data = [133.0, 132.9, 133.3, 133.1, 133.1]
# 绘图的5个日期:指定年、月、日
dates = [datetime(year=2019, month=10, day=10),
datetime(year=2019, month=11, day=10),
datetime(year=2019, month=12, day=10),
datetime(year=2020, month=1, day=10),
datetime(year=2020, month=2, day=10)]
# 绘图:传入时间和数据
fig = go.Figure(data=[go.Ohlc(
x=dates,
open=open_data,
high=high_data,
low=low_data,
close=close_data)])
fig.show()
增加悬停信息hovertext
悬停信息指的是:在图形中数据本身是不能看到的,当我们将光标移动到图中便可以看到对应的数据。
还是通过苹果公司股票的数据为例:
代码语言:javascript复制hovertext=[] # 添加悬停信息
for i in range(len(df['AAPL.Open'])): # <br>表示
hovertext.append('Open: ' str(df['AAPL.Open'][i]) '<br>Close: ' str(df['AAPL.Close'][i]))
# 结果表现形式
['Open: 127.489998<br>Close: 127.830002',
'Open: 127.629997<br>Close: 128.720001',
'Open: 128.479996<br>Close: 128.449997']
上面图中的红色部分就是悬停信息
基于时间序列
绘图数据
下面开始介绍的是如何绘制基于时间序列time series的股票图形,使用的是Plotly中自带的股票数据:
代码语言:javascript复制stocks = px.data.stocks()
stocks.head() # 显示前5行数据
第一个字段是日期时间,其余字段是不同的公司名称:谷歌、苹果、亚马逊等
基于px实现
我们利用plotly_express来实现基础图形的绘制,选取的公司是FB:Facebook
代码语言:javascript复制# 绘制FB股票走势
fig = px.line(
stocks,
x='date',
y='FB'
)
fig.update_layout(title={
'text':'Facebook股票走势',
'x':0.52,
'y':0.96,
'xanchor':'center',
'yanchor':'top'
})
fig.show()
基于go实现
下面采用的是基于go方法实现:
代码语言:javascript复制import pandas as pd
import numpy as np
# 两个接口
import plotly_express as px
import plotly.graph_objects as go
# 基于go
fig = go.Figure([go.Scatter(
x=stocks['date'],
y=stocks['FB'])])
fig.update_layout(title={
'text':'Facebook股票走势',
'x':0.52,
'y':0.96,
'xanchor':'center',
'yanchor':'top'
})
fig.show()
共享时间轴
代码语言:javascript复制import plotly.express as px
stock = px.data.stocks(indexed=True) - 1 # 将原始数据减掉1
stock.head()
代码语言:javascript复制fig = px.bar(
stock, # 数据
x=stock.index, # x轴
y="GOOG" # y轴
)
fig.show()
多面图共享时间轴
代码语言:javascript复制fig = px.area(
stock,
facet_col="company", # 根据公式显示不同的元素
facet_col_wrap=3 # 每行显示的图形数量
)
fig.show()
改变参数每行显示2个图形:
代码语言:javascript复制fig = px.area(
stock,
facet_col="company",
facet_col_wrap=2 # 每行显示的图形数量
)
fig.show()
Label标签个性设置
代码语言:javascript复制fig = px.line(
df4, # 绘图数据
x="date", # x轴标签
y=df4.columns,
hover_data={"date": "|%B %d, %Y"}, # 悬停信息设置
title='标签个性化设置-居中' # 图标题
)
fig.update_xaxes(
dtick="M1", # 表示one month:每个月显示一次
tickformat="%bn%Y", # 日期显示模式
ticklabelmode='instant' # ticklabelmode模式:居中 'instant', 'period'
)
fig.show()
基于直方图的时间序列实现
代码语言:javascript复制import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
# 读取在线csv文件
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.histogram( # 直方图
df,
x="Date",
y="AAPL.Open",
histfunc="avg", # 直方图函数
title="时间轴的直方图实现")
fig.update_traces(xbins_size="M1") # 按月显示
fig.update_xaxes(
showgrid=False,
dtick="M1", # 按月显示
ticklabelmode="period", # instant period
tickformat="%bn%Y" # 标签显示模式
)
fig.update_layout(bargap=0.1)
fig.show()
上面绘制的是单纯的直方图,再此基础上可以结合散点图来进行展示:
代码语言:javascript复制import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
# 1、生成直方图
fig = px.histogram(
df,
x="Date",
y="AAPL.Open",
histfunc="avg",
title="直方图 散点图")
# 2、更新轨迹:按月显示
fig.update_traces(xbins_size="M1") # 每个柱子显示几个月的数据:M1显示一个月 M2表示2个月
# 3、设置x轴
fig.update_xaxes(
showgrid=True,
dtick="M1", # 按月显示
ticklabelmode="period", # instant period
tickformat="%bn%Y"
)
# 4、每个柱状图间隔
fig.update_layout(bargap=0.1)
# 5、红色轨迹的设置
fig.add_trace(go.Scatter(
mode="lines", # ['lines', 'markers', 'text']
x=df["Date"], # 两个轴的数据
y=df["AAPL.Open"],
name="daily")) # 轨迹名称
fig.show()
指定交易日
代码语言:javascript复制import plotly.graph_objects as go
import pandas as pd
df = pd.DataFrame(dict(
# 横轴
date=["2019-01-10",
"2019-02-10",
"2019-03-10",
"2019-04-10",
"2019-05-10",
"2019-06-10"
],
# 纵轴
value=[10,12,13,11,12,13]
))
df
代码语言:javascript复制# 添加画布
fig = go.Figure()
# 添加不同的轨迹
fig.add_trace(go.Scatter( # 散点图
name="轨迹1", # 轨迹名称
mode="markers lines", # 轨迹模式 :标记 折线
x=df["date"], # 两个轴的数据
y=df["value"],
marker_symbol="star" # 标记符号:星星star
))
fig.add_trace(go.Scatter(
name="轨迹2",
mode="markers lines",
x=df["date"],
y=df["value"],
xperiod="M1", # x轴时间阶段显示模式:以1个月为基准
xperiodalignment="start" # start左边 middle中间 end右边
))
fig.add_trace(go.Scatter(
name="轨迹3",
mode="markers lines",
x=df["date"],
y=df["value"],
xperiod="M1",
xperiodalignment="middle"
))
fig.add_trace(go.Scatter(
name="轨迹4",
mode="markers lines",
x=df["date"],
y=df["value"],
xperiod="M1",
xperiodalignment="end"
))
fig.add_trace(go.Bar( # 柱状图
name="轨迹5",
x=df["date"],
y=df["value"],
xperiod="M1",
xperiodalignment="middle"
))
fig.update_xaxes(showgrid=True, ticklabelmode="period")
fig.show()
指定交易范围
在某个时间范围内进行绘图,还是以苹果公司股票为例:
代码语言:javascript复制# px 实现
import plotly.express as px
import pandas as pd
# 苹果公司数据
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.line(df,
x='Date', # x轴
y='AAPL.High', # y轴
range_x=['2015-07-01','2016-8-31']) # 指定交易时间范围
fig.show()
带有区间滑块绘图
代码语言:javascript复制import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.line(df,
x='Date',
y='AAPL.Open',
title='带有区间滑块绘图')
fig.update_xaxes(rangeslider_visible=True) # 开启区间滑块
fig.show()
滑块和时间按钮结合
除了滑块,我们还可以在图形中还可以设置按钮进行选择:
代码语言:javascript复制import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.line(
df,
x='Date',
y='AAPL.High',
title='带有滑块和按钮的时间序列绘图')
fig.update_xaxes(
rangeslider_visible=True, # 开始显示
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"), # 往前推一个月
dict(count=6, label="6m", step="month", stepmode="backward"), # 往前推6个月
dict(count=1, label="YTD", step="year", stepmode="todate"), # 只显示今年数据
dict(count=1, label="1y", step="year", stepmode="backward"), # 显示过去一年的数据
dict(step="all") # 显示全部数据
])
)
)
fig.show()
隐藏周末和交易日
1、首先看看在某个具体的时间段内,如果我们不对非交易日进行处理,图形会是什么样子?
代码语言:javascript复制# 默认形式
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.scatter(
df,
x='Date',
y='AAPL.High',
range_x=['2015-12-01', '2016-01-31'], # 指定绘图时间范围
title="非交易日(隐藏)")
fig.show()
2、指定需要隐藏的时间:可以是星期,也可以是具体的某天
代码语言:javascript复制# 隐藏周末和节假日
fig = px.scatter(
df,
x='Date', y='AAPL.High',
range_x=['2015-12-01', '2016-01-15'],
title="隐藏周末和节假日(指定日期)")
fig.update_xaxes(
rangebreaks=[
dict(bounds=["sat", "mon"]), # 隐藏周六、周一
dict(values=["2015-12-25", "2016-01-01"]) # 隐藏具体日期
]
)
fig.show()
隐藏非交易时间
在一天中并不是24小时都在交易的,我们需要对非交易时间段进行隐藏:
代码语言:javascript复制import plotly.express as px
import pandas as pd
import numpy as np
np.random.seed(1)
work_week_40h = pd.date_range(
start='2020-03-01',
end='2020-03-07',
freq="BH" # 数据产生的频率:按照小时
)
work_week_40h
代码语言:javascript复制df5 = pd.DataFrame(dict(
date = work_week_40h,
value = np.cumsum(np.random.rand(40)-0.5)
))
fig = px.scatter(df5,
x="date",
y="value",
title="排除非交易时间段")
fig.update_xaxes(
rangebreaks=[ # 排除时间段
dict(bounds=[17, 9], pattern="hour"), # 排除下午5点(17点)到上午9点的时间h
]
)
fig.show()
实战案例
下面我们通过A股中的3个股票来实际绘图:
- 中国平安
- 平安银行
- 福建金森
tushare
tushare是一个提供财经类数据的网站,包含:股票、债券、期货、基金等,主要特点是:
- 数据丰富:拥有丰富的数据内容,如股票、基金、期货、数字货币等行情数据,公司财务、基金经理等基本面数据
- 获取简单:SDK开发包支持语言,同时提供HTTP Restful接口,最大程度方便不同人群的使用
- 落地方便:提供多种数据储存方式,如Oracle、MySQL,MongoDB、HDF5、CSV等,为数据获取提供了性能保证
为了使用这些数据,我们需要安装tushare库:
代码语言:javascript复制pip install tushare # 下图显示安装成功
获取数据
我们以获取中国平安的数据为例:14个字段有开盘价open、最高价high等;每个网站机构采集数据的标准不同,本文中的数据仅供参考学习。
代码语言:javascript复制import pandas as pd
import tushare as ts
pingan = ts.get_hist_data("603018") # 股票代码要事先准备
pingan # 数据显示总共607行,14个字段
往数据中添加两个字段:
代码语言:javascript复制pingan = pingan.reset_index()
pingan["code_name"] = "中国平安"
pingan["code"] = "603018"
# 全部字段
Index(['date', 'open', 'high', 'close', 'low', 'volume', 'price_change',
'p_change', 'ma5', 'ma10', 'ma20', 'v_ma5', 'v_ma10', 'v_ma20',
'turnover', 'code_name', 'code'],
dtype='object')
同样方法可以获取平安银行和福建金森的股票数据
OHLC绘图
代码语言:javascript复制fig = go.Figure(data=go.Ohlc(
x=pingan['date'], # 传入日期
open=pingan['open'], # 传入4份数据
high=pingan['high'],
low=pingan['low'],
close=pingan['close']
))
fig.update(layout_xaxis_rangeslider_visible=False) # 隐藏滑块
fig.update_xaxes(
rangebreaks=[ # 设置隐藏数据
dict(bounds=["sat", "sun"]), # 隐藏周六、周日
]
)
fig.show()
开启显示滑块:fig.update(layout_xaxis_rangeslider_visible=True)
合并数据绘图
我们将3个股票的数据进行合并再绘图,使用的是concat函数:
代码语言:javascript复制# tushare_data
td = pd.concat([pingan,pinganbank,jinsen],axis=0).reset_index(drop=True) # 指定横纵axis=0上的合并数据
td
3个股票的OHLC绘图:
代码语言:javascript复制fig = go.Figure()
fig.add_trace(go.Scatter(
x=pingan['date'],
y=pingan['open'],
mode='lines',
name='中国平安'
))
fig.add_trace(go.Scatter(
x=pinganbank['date'],
y=pinganbank['open'],
mode='lines',
name='平安银行'
))
fig.add_trace(go.Scatter(
x=jinsen['date'],
y=jinsen['open'],
mode='lines',
name='福建金森'
))
fig.update_xaxes(
rangeslider_visible=True, # 开启显示滑块
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"), # 往后推一个月
dict(count=6, label="6m", step="month", stepmode="backward"), # 往后推6个月
dict(count=1, label="YTD", step="year", stepmode="todate"), # 只显示今年数据
dict(count=1, label="1y", step="year", stepmode="backward"), # 显示过去一年的数据
dict(step="all") # 显示全部数据
])
)
)
fig.show()
扩展阅读
- 酷炫!36张图爱上高级可视化神器Plotly_Express
- Plotly玩转散点图
- Plotly玩转饼图
- Plotly玩转漏斗图
- Plotly玩转柱状图
- Plotly玩转气泡图