Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

python - How to change the layout dynamically? How to add and remove layout objects properly?

I need to build an app with many plots. It will have some tabs, and one gridplot within the tabs with some plots. In addition I need to update the plots layout dynamically when the server is running.

  • Remove or add some plots
  • Remove or add some tabs

I have read this thread, where Bryan (@bigreddot) says:

The most well-used and understood (as well as more efficient) method is to create your plots once, up front, then update only their data when they need to change.

Bokeh's layout capability is ambitious and complicated. It works well in a number of situations but I can easily believe there are update bugs that might be exposed when replacing complicated composite models like entire plots deep in a nested layout.

I have written the following example where I update the layout in four different ways:

  1. Replacing the old plot by the children attribute on the layout object.
  2. Replacing the layout with curdoc()
  3. Replacing the plot using remove() and append()
  4. Inserting a new plot using insert()
from bokeh.models import Button, ColumnDataSource
from bokeh.layouts import column
from bokeh.plotting import curdoc, figure

# ------------------- PLOT 1 --------------------------- #

plot_1 = figure(
    width=400,
    height=400,
)

x = [1, 2, 3, 4]
y = [4, 3, 2, 1]

source = ColumnDataSource(data=dict(x=x, y=y))

plot_1.circle(
    x='x',
    y='y',
    source=source,
    radius=0.5,
    fill_alpha=0.6,
    fill_color='green',
)

# ------------------- PLOT 2 --------------------------- #

plot_2 = figure(
    width=400,
    height=400,
)

plot_2.circle(
    x='x',
    y='y',
    source=source,
    radius=0.5,
    fill_alpha=0.6,
    fill_color='red',
)

# ------------------- PLOT 3 --------------------------- #

plot_3 = figure(
    width=400,
    height=400,
)

plot_3.circle(
    x='x',
    y='y',
    source=source,
    radius=0.5,
    fill_alpha=0.6,
    fill_color='yellow',
)

# ------------------- BUTTONS --------------------------- #

def replace_by_children_attr():
    column_1.children = buttons + [plot_2]

def replace_by_curdoc():
    column_2 = column(buttons + [plot_2])

    curdoc().clear()
    curdoc().add_root(column_2)

def replace_by_remove_append():
    column_1.children.remove(plot_1)
    column_1.children.append(plot_2)

def insert_plot():
    column_1.children.insert(2, plot_3)

button_1 = Button(label="Replace plot by children attribute", button_type="success")
button_1.on_click(replace_by_children_attr)

button_2 = Button(label="Replace plot by curdoc", button_type="success")
button_2.on_click(replace_by_curdoc)

button_3 = Button(label="Replace plot remove-append", button_type="success")
button_3.on_click(replace_by_remove_append)

button_4 = Button(label="Insert plot", button_type="success")
button_4.on_click(insert_plot)

# ------------------- LAYOUT --------------------------- #

buttons = [button_1, button_2, button_3, button_4]
column_1 = column(buttons + [plot_1])

curdoc().add_root(column_1)

I realized that if I press the button "Replace plot by children attribute" the layout changes a little. But when I press "Replace plot by curdoc" the layout is not changed:
  • So, which of these options is the best solution?
  • Any of these solutions are going to give me problems? I know at least the first option is going to give me problems for sure

Note: Actually, what I want to avoid is to restart the bokeh server to rebuild the layout because it takes a while. And I need to do it very often.

Note 2: Bokeh version 0.12.14

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...