3

I have some difficulties to use the Widget callback with Bokeh. With the help of a checkbox widget, I would like to show/hide the corresponding plots.

The difference with this question, is that I would like a plot for each glyph(and not all the glyphs on one same plot). For example, if I tick/untick "b" I would like to see a new plot of the glyph.

Edit: New version of my code

    from bokeh.io import output_file, show
    from bokeh.layouts import column, widgetbox, row
    from bokeh.models import ColumnDataSource
    from bokeh.plotting import figure
    from bokeh.models.widgets import CheckboxGroup
    from bokeh.models import CustomJS
    import pandas as pd
    import numpy as np

    if __name__ == '__main__':

        # Plot tools
        TOOLS = 'box_select,box_zoom,reset'

        # Data Source
    df = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
    source = ColumnDataSource(df)

    # Create a new glyph and share ranges
    g = figure(plot_width=1300, plot_height=150, title='a', tools=TOOLS)
    g.circle(source=source, x='a', y='a')

    glyph_list = []

    for glyph in range(0, len(source.column_names)):
        glyph_list.append((figure(plot_width=1300, plot_height=150, x_range=g.x_range, title=source.column_names[glyph],
                                 tools=TOOLS)))

        glyph_list[glyph].circle(source=source, x='a', y=source.column_names[glyph])

    # Select the glyphs to plot
    initial_list = [0] * len(source.column_names)

    ## example of a change
    initial_list[2] = 1

    # Callback
    code = """
            ????
          """

    callback = CustomJS(args=dict(source=source), code=code) #????

    # Add checkbox widget
    checkbox_group = CheckboxGroup(labels=source.column_names,
                                   callback=callback,
                                   active=initial_list)

    plot_list = []
    for i in range(0, len(source.column_names)):
        if checkbox_group.active[i] == 1:
            plot_list.append(glyph_list[i])

    checkbox_group.js_on_change('active', callback) # ???


    layout = row(column(plot_list), widgetbox(checkbox_group))
    show(layout)
Hosh
  • 33
  • 1
  • 4
  • Could you elaborate on "...a plot for each data (and not all the lines on one same plot)...". Do you mean make visible on/off different axes? Those axes are in a grid? would they be in a column with dimensions: rows x 1 ? or a grid: rows x columns ? – Pablo Reyes Jun 05 '17 at 18:21

1 Answers1

0

It is easier to realise it using Python on_click handler instead of CustomJS callback:

from bokeh.layouts import column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import CheckboxGroup
from bokeh.plotting import curdoc, figure
from bokeh.client import push_session
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4), columns = ['a', 'b', 'c', 'd'])
source = ColumnDataSource(df)

def checkbox_click_handler(selected_checkboxes):
    visible_glyphs = layout.children
    for index, glyph in enumerate(glyph_list):
        if index in selected_checkboxes:
            if glyph not in visible_glyphs:
                layout.children.append(glyph)
        else:
            if glyph in visible_glyphs:
                layout.children.remove(glyph)

checkbox_group = CheckboxGroup(labels = list(df.columns.values), active = [0, 1, 2, 3, 4])
checkbox_group.on_click(checkbox_click_handler)

layout = column()
layout.children.append(checkbox_group)

glyph_list = []
for index, letter in enumerate(df.columns.values):
    glyph = figure(plot_width = 800, plot_height = 240, title = letter, name = letter)
    glyph.circle(source = source, x = 'a', y = letter)
    glyph_list.append(glyph)
    layout.children.append(glyph)

session = push_session(document = curdoc())
session.show(layout)
session.loop_until_closed()
Tony
  • 7,767
  • 2
  • 22
  • 51
  • Cannot push session document because we failed to connect to the server (to start the server, try the 'bokeh serve' command) : when running- session = push_session(document = curdoc()):::: do the following::: import os;os.system('bokeh serve') – azazelspeaks Sep 19 '18 at 23:15
  • Open command line (Windows) or Terminal (Mac) and type "bokeh serve" to start the bokeh server – Tony Sep 22 '18 at 14:23