在同一图形上绘制Bokeh的烛台和音量条

2022-04-07 00:00:00 python bokeh

问题描述

基本上,我想做与shown in this question相同的事情,但增加了两个修改:

  • 将烛台和体积合并为一个图形
  • 有两个y轴,这样它们可以独立滚动/缩放(例如,当烛台轴被滚轮缩放时,只有烛台应该改变大小,而音量条不应该改变-音量条反之亦然)

这是Bokeh可以做的事情吗?


解决方案

可以将这两个图形合并为一个。但据我所知,不可能通过单击轴来选择数据。而是添加图例以隐藏不在焦点中的数据。

如果您还没有数据,请先运行此代码段。

import bokeh
bokeh.sampledata.download()

这是创建图形的代码。

import pandas as pd
import numpy as  np
from bokeh.plotting import figure, output_notebook, show
from bokeh.sampledata.stocks import MSFT
from bokeh.models import LinearAxis, Range1d, Segment, Legend
output_notebook()

df = pd.DataFrame(MSFT)[:50]
df["date"] = pd.to_datetime(df["date"])
inc = df.close > df.open
dec = df.open > df.close
w = 12*60*60*1000 # half day in ms

TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
p = figure(x_axis_type="datetime", tools=TOOLS, 
           plot_width=700, plot_height=300, 
           title = "MSFT Candlestick with Volume")
p.add_layout(Legend(click_policy="hide", orientation='horizontal', spacing=20), 'below')
# left y axis
low, high  = df[['open', 'close']].min().min(), df[['open', 'close']].max().max()
diff = high-low
p.y_range = Range1d(low-0.1*diff, high+0.1*diff)
p.yaxis.axis_label = 'Price'
p.segment(df.date, df.high, df.date, df.low, color="black", legend_label='Candlestick')
p.vbar(df.date[inc], w, df.open[inc], df.close[inc], 
       fill_color="#D5E1DD", line_color="black", legend_label='Candlestick')
p.vbar(df.date[dec], w, df.open[dec], df.close[dec], 
       fill_color="#F2583E", line_color="black", legend_label='Candlestick')
# right y axis
p.extra_y_ranges.update({'two':  Range1d(0, 1.1*df.volume.max())})
p.add_layout(LinearAxis(y_range_name='two', axis_label='Volume' ), 'right')
p.vbar(df.date, w, df.volume, [0]*df.shape[0], alpha=0.5, level='underlay', 
       legend_label='Volume', y_range_name='two')
show(p)
创建的图形如下所示:

相关文章