Bokeh: Widget to Show/Hide Figures

大城市里の小女人 提交于 2020-04-10 05:17:40

问题


Looking to do something along the lines of a UI as here: Bokeh: Using Checkbox widget to hide and show plots wherein I can selectively show/hide the whole figure in a column of figures. A drop down menu (OptionMenu with multiple selections) where I could select which plots showed up (assuming I could name the figures) would be preferable.

I am not familiar with JS, any guidance? (Thanks in advance)

I'd hope that the image wouldn't be visible anymore and the next figure would jump up like so:

eg:

I have multiple figures in a column generated as:

from bokeh.io import output_file, show
from bokeh.layouts import column
from bokeh.plotting import figure

output_file("layout.html")

x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]

# create a new plot
s1 = figure(plot_width=250, plot_height=250, title=None)
s1.circle(x, y0, size=10, color="navy", alpha=0.5)

# create another one
s2 = figure(plot_width=250, plot_height=250, title=None)
s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5)

# create and another
s3 = figure(plot_width=250, plot_height=250, title=None)
s3.square(x, y2, size=10, color="olive", alpha=0.5)

# put the results in a column and show
show(column(s1, s2, s3))

回答1:


Plots don't have a visible toggle, at least as of version 0.13. So you will have to reset the children value of the layout widget. I'm not quite sure what interaction you intend with a dropdown. Here is a complete example with a checkbox:

from bokeh.io import output_file, show
from bokeh.layouts import column, row
from bokeh.plotting import figure
from bokeh.models import CheckboxGroup, CustomJS

output_file("layout.html")

x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]

s1 = figure(plot_width=250, plot_height=250, title=None)
s1.circle(x, y0, size=10, color="navy", alpha=0.5)

s2 = figure(plot_width=250, plot_height=250, title=None)
s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5)

s3 = figure(plot_width=250, plot_height=250, title=None)
s3.square(x, y2, size=10, color="olive", alpha=0.5)

col = column(s1, s2, s3)

checkbox = CheckboxGroup(labels=["Plot 1", "Plot 2", "Plot 3"],
                         active=[0, 1, 2], width=100)

callback = CustomJS(args=dict(plots=[s1,s2, s3], col=col, checkbox=checkbox), code="""
const children = []
for (const i of checkbox.active) {
     children.push(plots[i])
} 
col.children = children
""")
checkbox.js_on_change('active', callback)

show(row(checkbox, col))

You could do something similar with a MultiSelect:

select = MultiSelect(options=[("0", "Plot 1"), ("1", "Plot 2"), ("2", "Plot 3")],
                       value=["0", "1", "2"], width=100)

callback = CustomJS(args=dict(plots=[s1,s2, s3], col=col, select=select), code="""
const children = []
for (const i of select.value) {
    children.push(plots[i])
}
col.children = children
""")
select.js_on_change('value', callback)

Small FYI that that code is a little sloppy—it's relying on JS implicitly casting strings like "0" to numbers.




回答2:


s1.tags, s2.tags, s3.tags = ['Foo'], ['Bar'], ['Arr'] # name your plots
plots = [s1, s2, s3]
labels = [(plots[i].tags[0]) for i in range(len(plots))]
active = list(range(0, len(plots)))

chkbx = CheckboxButtonGroup(labels=labels, active=active)

callback = CustomJS(args=dict(plots=plots, chkbx=chkbx), code="""
    for (let i = 0; i < plots.length; i++){
        plots[i].visible = chkbx.active.includes(i)
    }
    """)

chkbx.js_on_click(callback)

show(column([chkbx] + plots))

Thanks to @bigreddot and their answer for laying foundation for this solution.



来源:https://stackoverflow.com/questions/52415577/bokeh-widget-to-show-hide-figures

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!