9

I want to create a visualization where there are two line graphs that are updated with one new point per line graph per second.

I have recently read about bokeh and found out that it can be used in visualizing streams of data in real-time. However, I don't know how to code in it yet.

I would appreciate it if someone can show me how this task can be done using bokeh. Thanks!

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
jtitusj
  • 3,046
  • 3
  • 24
  • 40

2 Answers2

21

For bokeh-0.11.1:

Basically, you need to run you python app in the bokeh server. Then anyone can connect to the server and view the graph in realtime.

First, write your program. Use this code for example:

# myplot.py
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import random

p = figure(plot_width=400, plot_height=400)
r1 = p.line([], [], color="firebrick", line_width=2)
r2 = p.line([], [], color="navy", line_width=2)

ds1 = r1.data_source
ds2 = r2.data_source

@linear()
def update(step):
    ds1.data['x'].append(step)
    ds1.data['y'].append(random.randint(0,100))
    ds2.data['x'].append(step)
    ds2.data['y'].append(random.randint(0,100))  
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

curdoc().add_root(p)

# Add a periodic callback to be run every 500 milliseconds
curdoc().add_periodic_callback(update, 500)

Then run the server from the command line, with your program:

C:\>bokeh serve --show myplot.py

This will open the browser with your realtime graph.

For all the details see the bokeh server documentation.

bigreddot
  • 33,642
  • 5
  • 69
  • 122
Elad Joseph
  • 2,998
  • 26
  • 41
  • 4
    For fairly obtuse technical reasons, it is often preferred to update the entire `.data` attribute "at once" i.e. `ds.data = new_data` if you can. Also if you do it that way, the `trigger` calls are not necessary, the Bokeh server will pick up changes to entire properties automagically. – bigreddot Jun 09 '16 at 14:24
  • How is it possible to show only the last X points instead of squeezing all the dataset? – Alex Poca Jan 06 '17 at 13:10
  • `.stream` accepts a `rollover` parameter that says how many points to keep at max, before dropping points. – bigreddot Jun 23 '17 at 01:15
  • is there a way to add "windowing" to this example? If you run this, the graph gets more and more jammed with data, the axis windows don't automatically adjust. EDIT: nevermind I see Alan's answer below extends this example. – Tommy Dec 12 '17 at 14:58
  • What does `trigger` do here? I found the link to their source, and documentation, but the docstring is blank: https://bokeh.pydata.org/en/latest/docs/reference/model.html – Tommy Dec 12 '17 at 20:02
  • I know it's old answer but I would appreciate some help - if I were to open :5006/myplot in browser and after some time open the same address in next tab I would get two independent, different plots in two tabs. How can I make plot persistent over different tabs? –  Feb 09 '19 at 19:57
10

You can add scrolling to your graph by adding the following to the plot figure declaration:

p = figure(plot_width=400, plot_height=400)
p.x_range.follow="end"
p.x_range.follow_interval = 20
p.x_range.range_padding=0

where the follow_interval = the number of points that accumulate on the on the graph before it starts scrolling. I believe you can set the visible range on the chart, as well. FYI I got the scrolling code from the OHLC example on the bokeh GitHub page found here: https://github.com/bokeh/bokeh/tree/master/examples/app The OHLC is an example of streaming data using the "...= new_data" technique that bigreddot mentioned.

Alan Tate
  • 101
  • 1
  • 3