I have a simulation that runs in python and has hundreds of time steps. I am trying to use bokeh to visualize some of the simulation results at each time step in a browser window. The layout of the visualization is fixed, but the underlying data changes at each time step. I don’t want to have any interaction from the browser back to my simulation. I just want a one-way update to the browser to update the plots at the end of each simulation time step. Does anyone have recommendations or example code showing the best way to approach this?
I adapted code from https://bokeh.pydata.org/en/latest/docs/user_guide/server.html#updating-from-threads and came up with the code below (saved as
simulation_framework.py) using a dummy simulation update step that just picks random values for x and y. I can run with
bokeh serve --show simulation_framework.py but I am still interested if someone has other recommendations for how to do this.
from functools import partial from random import random from threading import Thread import os import time from bokeh.models import ColumnDataSource from bokeh.plotting import curdoc, figure from tornado import gen # this must only be modified from a Bokeh session callback source = ColumnDataSource(data=dict(x=, y=)) # This is important! Save curdoc() to make sure all threads # see the same document. doc = curdoc() @gen.coroutine def update(x, y): # source.stream(dict(x=[x], y=[y])) source.data = dict(x=[x], y=[y]) def blocking_task(): num_steps = 100 for ii in range(num_steps): print(ii) # do code for simulation time step ii here time.sleep(0.1) x, y = random(), random() # but update the document from callback doc.add_next_tick_callback(partial(update, x=x, y=y)) os._exit(0) p = figure(x_range=[0, 1], y_range=[0,1]) l = p.circle(x='x', y='y', source=source) doc.add_root(p) thread = Thread(target=blocking_task) thread.start()