作为概念验证的示范作品,我创建了四个OHLC蜡烛的散景图。
我想扩展演示以使绘图动画化,以便当前烛台移动并更新以响应其OHLC数据的变化。重要的一点是,只应更新最终蜡烛的组成部分(字形?),而不是整个情节。
目的是展示一种计算轻量级的方法,并且可以扩展到更大的图表,其中包含许多蜡烛以及对“实时”蜡烛的频繁更新。
是否有人能够在代码中概述或演示如何实现这一目标?
谢谢。
Jupyter笔记本Python代码(包括39秒的合成刻度数据,以方便4 x 10秒烛台动画):
from ipywidgets import interact
import numpy as np
from bokeh.plotting import figure, output_notebook, show
import datetime as dt
import pandas as pd
from math import pi
datum = dt.datetime.now()
time_delta = dt.timedelta(seconds=1)
tick_data = [(datum + (time_delta*1), 20),
(datum + (time_delta*2), 19.67603177022472),
(datum + (time_delta*3), 20.431878609290592),
(datum + (time_delta*4), 20.20576131687243),
(datum + (time_delta*5), 20.715609070433032),
(datum + (time_delta*6), 20.722416975732024),
(datum + (time_delta*7), 20.722027468712426),
(datum + (time_delta*8), 20.728022489796615),
(datum + (time_delta*9), 20.70996968619282),
(datum + (time_delta*10), 20.70096021947874),
(datum + (time_delta*11), 20.729546647699372),
(datum + (time_delta*12), 20.759081440837274),
(datum + (time_delta*13), 20.823807346441097),
(datum + (time_delta*14), 20.610018797947472),
(datum + (time_delta*15), 20.591932124168064),
(datum + (time_delta*16), 20.584175853951805),
(datum + (time_delta*17), 20.563650527527987),
(datum + (time_delta*18), 20.617504106758794),
(datum + (time_delta*19), 20.42010872326373),
(datum + (time_delta*20), 20.391860996799267),
(datum + (time_delta*21), 20.3913190739894),
(datum + (time_delta*22), 20.34308794391099),
(datum + (time_delta*23), 20.2225778590662),
(datum + (time_delta*24), 20.47050754458162),
(datum + (time_delta*25), 20.83193618858914),
(datum + (time_delta*26), 20.80978509373571),
(datum + (time_delta*27), 20.80917543057461),
(datum + (time_delta*28), 20.859506511541262),
(datum + (time_delta*29), 20.596402987349492),
(datum + (time_delta*30), 20.644024454266795),
(datum + (time_delta*31), 20.58183881183424),
(datum + (time_delta*32), 20.59023861538722),
(datum + (time_delta*33), 20.454961133973477),
(datum + (time_delta*34), 20.495334383308776),
(datum + (time_delta*35), 20.483818523599044),
(datum + (time_delta*36), 20.593964334705078),
(datum + (time_delta*37), 20.91518908025538),
(datum + (time_delta*38), 20.87942217480398),
(datum + (time_delta*39), 20.772392419854697)]
#Prepare to convert fractal tick data into candlesticks
candle_delta = dt.timedelta(seconds=10)
candle_close_time = datum + candle_delta
candle_data = []
#Initialise
op, hi, lo, cl = 0, 0, 0, 0
#Convert ticks to candlesticks
for (dtval, val) in tick_data:
if candle_close_time < dtval:
#store the completed candle
candle_data.append((candle_close_time, op, hi, lo, cl))
#increment to the next candle
candle_close_time += candle_delta
#Reset
op, hi, lo, cl = 0, 0, 0, 0
if dtval <= candle_close_time and op==0:
#set initial values
op, hi, lo, cl = val, val, val, val
elif dtval <= candle_close_time and op!=0:
#update values as appropriate
hi = val if val > hi else hi
lo = val if val < lo else lo
cl = val
#final tick
if dtval == tick_data[-1][0]:
#store the completed candle
candle_data.append((candle_close_time, op, hi, lo, cl))
#print(str(candle_data))
df = pd.DataFrame(candle_data, columns=list('dohlc'))
#For rectangle positioning
mids = (df.o + df.c)/2
#Rectangle height
spans = abs(df.c-df.o)
#Detect up / down candle body
inc = df.c > df.o
dec = df.o > df.c
#Candle width
w = 10 * 500
TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
p = figure(x_axis_type="datetime", tools=TOOLS, plot_width=500, title = "Four Candles")
p.xaxis.major_label_orientation = pi/4
p.grid.grid_line_alpha=0.3
#Wick
p.segment(df.d, df.h, df.d, df.l, color="#000000")
#Up body
p.rect(df.d[inc], mids[inc], w, spans[inc], fill_color="#09ff00", line_color="#09ff00")
#Down body
p.rect(df.d[dec], mids[dec], w, spans[dec], fill_color="#ff0000", line_color="#ff0000")
output_notebook()
show(p)