As an update to this, i examined the source code and also found some related posts. The keys to doing this were:
- VBox (in 0.7 for vertically aligned widgets)
- toolbar_location=None to remove toolbar for sub-plots
- assignment of x_range from main plot to sub-plots, to link panning behavior
Here is an example that puts this together, for future reference:
from bokeh.plotting import *
import numpy as np
from datetime import *
from bokeh.models import DatetimeTickFormatter
def concat(a, b):
return np.append(np.array(a), np.array(b))
def SMA(x, N):
return np.convolve(x, np.ones((N,))/N, mode=‘valid’)
def mr (n: int, sd=0.5, kappa=0.01, x0 = 100):
x = x0
vec =
for dw in np.random.normal(scale=sd, size=n):
dX = -kappa*(x - x0) + dw
x += dX
vec.append(x)
return vec
def daterange (Tstart: datetime, dt: int, n: int):
Ts = Tstart.timestamp()
return [datetime.utcfromtimestamp(Ts + i * dt) for i in range(0,n)]
yprices = mr (800, kappa=0.001)
xprices = daterange(datetime(2014,4,1,9,0,0), dt=30, n=800)
yma = SMA(yprices, 12)
xma = xprices[(len(yprices)-len(yma)):]
dfs = concat (np.zeros((2+len(yprices)-len(yma))), np.diff (yma,2))
yvol = np.array([abs(dfs[i]) * 10000 for i in range(0,len(yprices),4)])
xvol = daterange(datetime(2014,4,1,9,0,0), dt=120, n=200)
output_file(“/tmp/test.html”, “test”)
config_top = dict(
x_axis_type=“datetime”, x_range=[xprices[0], xprices[-1]],
plot_width=800, plot_height=400, background_fill = “#f0f0f0”, title_text_font_size=“14pt”,
min_border_bottom=0, min_border_top=0,
tools=“pan,wheel_zoom,box_zoom,select”)
config_lower = dict(
x_axis_type=“datetime”, x_range=[xprices[0], xprices[-1]],
plot_width=800, plot_height=200, background_fill = “#f0f0f0”, title_text_font_size=“14pt”,
min_border_bottom=0, min_border_top=0, toolbar_location=None)
xformatter = DatetimeTickFormatter(formats=dict(hours=[“%H:%m”]))
p1 = figure(title=‘prices’, **config_top)
p1.line(xprices, yprices, color=‘black’)
p1.line(xma, yma, color=‘red’)
p1.xaxis.formatter = xformatter
p2 = figure(title=None, **config_lower)
p2.rect(xvol, yvol/2, width=120, height=yvol, fill=‘blue’)
p2.x_range = p1.x_range
vbox = VBox()
vbox.children.append(p1)
vbox.children.append(p2)
show(vbox)
···
On Sunday, December 7, 2014 10:32:00 AM UTC-5, Jonathan Shore wrote:
I upgraded to Bokeh 0.7 so I could use VBox (which I noticed in the git repo). However, I have not figured the following out, if anyone can help:
- how does one avoid displaying the tool bar (I only want the toolbar on the top plot)
- can I latch on to a pan event (or drag) in one pane and apply to the other panes?
Thanks for any and all help.
On Saturday, December 6, 2014 7:24:51 PM UTC-5, Jonathan Shore wrote:
I just started using Bokeh’s python API. I have multiple time series that I want to plot on the same x-axis, but plot in separate vertically stacked areas (figures) due to distinct y-axes and to avoid visual clutter.
In ggplot I could accomplish this with vertical facets. Is there a way I can do something like this in Bokeh? I am aware of the gridplot() function to present a series of graphs in a grid, but:
- want a vertical stacking (and not horizontal + vertical)
- want to keep the x axis aligned
- want to allow for panning synchronously across the graphs
A typical layout I use with ggplot is a large facet (cartesian plotting area) for prices, and one or more smaller areas for signals. For example, 1 larger pane + 2 vertically smaller panes aligned on the same axis:
-----------------|
>
>
-----------------|
-----------------|
}-----------------|
-----------------|
}-----------------|
0 1 2 3 4 5 6 7
Facets are quite popular in the R / ggplot world, so suspect there are others who would like to do this.
–
Jonathan Shore
Systematic Trading LLC