Reputation: 101
I have database with pairs of Bokeh plot components for embedding - Script and Div HTML elements. I would like to embed more independent Bokeh plots on single page. The template code bellow renders same first plot for each iteration, please advise what Im doing wrong..
PS: I know for embedding multiple plots you can export single Script for all plots and unique Div for each of them. This doesnt work for me, because each plot will be generated (updated) at different time.
Thanks you for help!
{% for plot in plots %}
<div>
{{ plot.plot_div | safe }}
{{ plot.plot_script | safe }}
</div>
{% endfor %}
Upvotes: 0
Views: 646
Reputation: 34618
You should probably use the recently added json_item
for embedding in this case. This function produces a JSON representation of whatever it is passed, that can be embedded separately using a JavaScript call to Bokeh.embed.embed_items
in your template.
Here is a complete example based on Flask but the idea should transfer directly to Django:
from __future__ import print_function
import json
from bokeh.embed import json_item
from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.sampledata.iris import flowers
from flask import Flask
from jinja2 import Template
app = Flask(__name__)
page = Template("""
<!DOCTYPE html>
<html lang="en">
<head>
{{ resources }}
</head>
<body>
<div id="myplot"></div>
<div id="myplot2"></div>
<script>
fetch('/plot')
.then(function(response) { return response.json(); })
.then(function(item) { Bokeh.embed.embed_item(item); })
</script>
<script>
fetch('/plot2')
.then(function(response) { return response.json(); })
.then(function(item) { Bokeh.embed.embed_item(item, "myplot2"); })
</script>
</body>
""")
colormap = {'setosa': 'red', 'versicolor': 'green', 'virginica': 'blue'}
colors = [colormap[x] for x in flowers['species']]
def make_plot(x, y):
p = figure(title = "Iris Morphology", sizing_mode="fixed", plot_width=400, plot_height=400)
p.xaxis.axis_label = x
p.yaxis.axis_label = y
p.circle(flowers[x], flowers[y], color=colors, fill_alpha=0.2, size=10)
return p
@app.route('/')
def root():
return page.render(resources=CDN.render())
@app.route('/plot')
def plot():
p = make_plot('petal_width', 'petal_length')
return json.dumps(json_item(p, "myplot"))
@app.route('/plot2')
def plot2():
p = make_plot('sepal_width', 'sepal_length')
return json.dumps(json_item(p))
if __name__ == '__main__':
app.run()
Upvotes: 0