Yes it is possible to merge the two figures into one. And since bokeh 3.2.0 it is possible to scroll the axis independently.
A legend is added to hide the data which is not in your focus as well.
If you don't have the data yet, run this snippet first.
import bokeh
bokeh.sampledata.download()
This is the code to create the figure.
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,
width=700,
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')
wheel_zoom = p.toolbar.tools[1]
wheel_zoom.zoom_together='none' # can be 'none', 'cross', 'all'
p.toolbar.active_scroll = wheel_zoom
show(p)
The created figure looks like this.
