I am trying to combine the two bokeh examples embed_multiple.py and simple_stream.py to have dynamic graphs served within a template from bokeh-server.
The aim is to have dynamic graphs embedded in a layout with additional information such as text and links.
The below code will produce the HTML file as expected from embed_multiple.py, but the bokeh_server window only displays the plots (no header / body info is preserved).
import time
import numpy as np
from bokeh.plotting import cursession, figure, show, output_server
from bokeh.models import GlyphRenderer, Range1d
from bokeh.embed import components
from jinja2 import Template
# static pages requirements
import webbrowser
import os
import six
output_server("simple_stream")
# live graph example data
x = np.linspace(0, 4*np.pi, 200)
y = np.sin(x)
# create some data
x1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y1 = [0, 8, 2, 4, 6, 9, 5, 6, 25, 28, 4, 7]
x2 = [2, 5, 7, 15, 18, 19, 25, 28, 9, 10, 4]
y2 = [2, 4, 6, 9, 15, 18, 0, 8, 2, 25, 28]
x3 = [0, 1, 0, 8, 2, 4, 6, 9, 7, 8, 9]
y3 = [0, 8, 4, 6, 9, 15, 18, 19, 19, 25, 28]
# select the tools we want
TOOLS="pan,wheel_zoom,box_zoom,reset,save"
# live graph example figure
p = figure(title="Simple streaming example")
p.line(x,y, color="Orange", line_width=2)
# the red and blue graphs will share this data range
xr1 = Range1d(start=0, end=30)
yr1 = Range1d(start=0, end=30)
# only the green will use this data range
xr2 = Range1d(start=0, end=30)
yr2 = Range1d(start=0, end=30)
# build our figures
p1 = figure(x_range=xr1, y_range=yr1, tools=TOOLS, plot_width=300, plot_height=300)
p1.scatter(x1, y1, size=12, color="red", alpha=0.5)
p2 = figure(x_range=xr1, y_range=yr1, tools=TOOLS, plot_width=300, plot_height=300)
p2.scatter(x2, y2, size=12, color="blue", alpha=0.5)
p3 = figure(x_range=xr2, y_range=yr2, tools=TOOLS, plot_width=300, plot_height=300)
p3.scatter(x3, y3, size=12, color="green", alpha=0.5)
# plots can be a single PlotObject, a list/tuple, or even a dictionary
plots = {'Orange': p, 'Red': p1, 'Blue': p2, 'Green': p3}
script, div = components(plots)
template = Template('''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bokeh Scatter Plots</title>
<h1> embedding multiple graphs - can we do it live?</h1>
<b> So, this text will show up on the static page, but not from Bokeh server! <br \> I must be missing something... </b>
<style> div{float: left;} </style>
<link rel="stylesheet" href="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.0.min.css" type="text/css" />
<script type="text/javascript" src="http://cdn.bokeh.org/bokeh/release/bokeh-0.9.0.min.js"></script>
{{ script }}
</head>
<body>
{% for key in div.keys() %}
{{ div[key] }}
{% endfor %}
</body>
</html>
''')
show(template.render(script=script, div=div))
html_file = 'embed_multiple.html'
with open(html_file, 'w') as textfile:
textfile.write(template.render(script=script, div=div))
url = 'file:{}'.format(six.moves.urllib.request.pathname2url(os.path.abspath(html_file)))
webbrowser.open(url)
ds = p.select({"type": GlyphRenderer})[0].data_source
while True:
oldx = ds.data["x"]
newx = np.hstack([oldx, [oldx[-1] + 4*np.pi/200]])
ds.data["x"] = newx
ds.data["y"] = np.sin(newx)
cursession().store_objects(ds)
time.sleep(0.5)
My suspicion is that I am using 'show' incorrectly:
show(template.render(script=script, div=div))
Thanks for your time!
Edit:
Using the separate http.server alongside bokeh_server approach outlined in the embed examples (modified animated.py) still seems to strip HTML! (h1 in this example)
I'm still a little shaky with what you're trying to do exactly, but I think one concept you're not doing right is showing multiple plots (p - p3) in the right way.
This seems to be a nice tutorial on how to format your multi-plot layouts with bokeh
. I haven't looked at their API until tonight but it seems pretty intuitive.
If you're having issues with something else in the code, maybe edit your question to better reflect that issue and I'll take another stab at it.