我一直在做一个项目,使用bokeh可视化来显示基于代理的模型(ABM)模拟的结果。在recent post中,我得到了帮助,使我的数据在一个非常简化的模拟版本中正确地流式传输。我的下一个任务是在布局中添加一个“重置”按钮,这样我就可以将我的图形恢复到初始状态,并再次从“步骤0”运行模拟。我认为这是一个很简单的任务。令人惊讶的是,似乎没有一种简单的方法可以做到这一点。我尝试了几种不同的方法,包括重新初始化所有数据和重新填充ColumnDataSources,但我无法使以前运行的模拟中的数据消失。下面是一个独立的代码示例,说明了问题:
import colorcet as cc
from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models import Button
from bokeh.layouts import column
import random
def make_document(doc):
# make a list of groups
strategies = ['DD', 'DC', 'CD', 'CCDD']
# initialize some vars
step = 0
callback_obj = None
colors = cc.glasbey_dark
#num_colors = len(colors)
# create a list to hold all CDSs for active strategies in next step
sources = []
# Create a figure container
fig = figure(title='Streaming Line Plot - Step 0', plot_width=1400, plot_height=400)
# get step 0 data for initial strategies
for i in range(len(strategies)):
step_data = dict(step=[step],
strategy = [strategies[i]],
ncount=[random.choice(range(1, 100))])
data_source = ColumnDataSource(step_data)
color = colors[i]
# this will create one fig.line renderer for each strategy & its data for this step
fig.line(x='step', y='ncount', source=data_source, color=color, line_width=2)
# add this CDS to the sources list
sources.append(data_source)
def button1_run():
nonlocal callback_obj
if button1.label == 'Run':
button1.label = 'Stop'
button1.button_type='danger'
callback_obj = doc.add_periodic_callback(button2_step, 100)
else:
button1.label = 'Run'
button1.button_type = 'success'
doc.remove_periodic_callback(callback_obj)
def button2_step():
nonlocal step
data = []
step += 1
fig.title.text = 'Streaming Line Plot - Step '+str(step)
for i in range(len(strategies)):
step_data = dict(step=[step],
strategy = [strategies[i]],
ncount=[random.choice(range(1, 100))])
data.append(step_data)
for source, data in zip(sources, data):
source.stream(data)
def button3_reset():
step = 0
fig.title.text = 'Streaming Line Plot - Step '+str(step)
for i in range(len(strategies)):
init_data = dict(step=[step],
strategy = [strategies[i]],
ncount=[random.choice(range(1, 100))])
reset_source = ColumnDataSource(init_data)
print(init_data)
color = colors[i]
# this will create one fig.line renderer for each strategy & its data for this step
fig.line(x='step', y='ncount', source=reset_source, color=color, line_width=2)
# add this CDS to the sources list
sources.append(reset_source)
# add on_click callback for button widget
button1 = Button(label="Run", button_type='success', width=390)
button1.on_click(button1_run)
button2 = Button(label="Step", button_type='primary', width=390)
button2.on_click(button2_step)
button3 = Button(label="Reset", button_type='warning', width=390)
button3.on_click(button3_reset)
doc.add_root(column(fig, button1, button2, button3))
doc.title = "Now with live updating!"
apps = {'/': Application(FunctionHandler(make_document))}
server = Server(apps, port=5004)
server.start()
if __name__ == '__main__':
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
在我的button3_reset
代码中,我试图做的基本上是在make_document
函数的顶部重复初始化。但是,即使该代码的工作原理相同(从在{{CD3}}步骤中的一个打印输出中明显),我不能使该图形重置为其初始空状态。我已经阅读了很多堆栈溢出帖子和其他bokeh文档,但对于我认为是一个简单的问题,还没有找到一个简单的答案:如何将bokeh线图重置回其原始状态,以便可以从其起点再次运行数据流
我正在使用Bokeh1.4.0(anaconda不会让我更新)、Python3.7.6、Spyder4.0.1以及Chrome&;勇敢的可视化浏览器
你的
button3_reset
代码并没有清理任何东西——它只是在现有内容的基础上添加新内容相反,您应该迭代
sources
列表,并将每个源的data
属性设置为代码中第一个循环中使用的初始值。也就是说,您还必须将该数据保存在某个地方相关问题 更多 >
编程相关推荐