Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get access and modify already existing Bokeh figure elements directly from javascript?

I am developing an application using Bokeh and Flask. Using server-side python code, it produces a plot embedded in a web page which contains a variety of user input elements aiming at configuring the plot.

I know that starting from Bokeh v0.12.x, there is an API allowing to create and manipulate plots directly from javascript.

The bit I am missing here is, starting from the Bokeh javascript object, how can I list and access the already instantiated figure objects (figure, line, ColumnDataSource, ...)? Using the BokehJS API, I would then be able to write javascript code translating webpage user events (checkbox, button click, text input, ...) into actions on the plot (change line color, hide lines, update data point values, ...).

like image 727
Astrum42 Avatar asked Oct 27 '17 16:10

Astrum42


1 Answers

Consider this very rudimentary example. I hope it can get you started.

Two sliders change x and y coordinates of the middle dot.

from bokeh.plotting import figure
from bokeh.resources import CDN
from bokeh.embed import file_html
from bokeh.models import ColumnDataSource
from jinja2 import Template

source = ColumnDataSource(data=dict(x=[1, 2, 3],
                                    y=[3, 2, 1]),
                          name='my-data-source')

p = figure()
l1 = p.line("x", "y", source=source)

# copied and modified default file.html template used for e.g. `file_html`
html_template = Template("""
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>{{ title|e if title else "Bokeh Plot" }}</title>
        {{ bokeh_css }}
        {{ bokeh_js }}
        <style>
          html {
            width: 100%;
            height: 100%;
          }
          body {
            width: 90%;
            height: 100%;
            margin: auto;
          }
        </style>
        <script>
            function change_ds_value(name, idx, value) {
                var ds = Bokeh.documents[0].get_model_by_name('my-data-source');
                ds.data[name][idx] = value;
                ds.change.emit();
            }
        </script>
    </head>
    <body>
        <div>
            {{ plot_div|indent(8) }}
            {{ plot_script|indent(8) }}
            <input type='range' min='-5' max='5'
                   onchange='change_ds_value("x", 1, this.value)'/>
            <input type='range' min='-5' max='5'
                   onchange='change_ds_value("y", 1, this.value)'/>
        </div>
    </body>
</html>
""")

html = file_html(p, CDN, template=html_template)
with open('test.html', 'wt') as f:
    f.write(html)
like image 161
Eugene Pakhomov Avatar answered Oct 10 '22 15:10

Eugene Pakhomov