Martendo
Martendo

Reputation: 101

Bokeh, Django - embedding more independent plots via Components

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

Answers (1)

bigreddot
bigreddot

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

Related Questions