# Live plot with interactivity

**URL:** <https://discourse.bokeh.org/t/live-plot-with-interactivity/10890>\
**Category:** Community Support\
**Created:** [September 25, 2023, 10:32pm UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890 "2023-09-25T22:32:07Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![reubenharry](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/reubenharry/32/6254_2.png) [@reubenharry](https://discourse.bokeh.org/u/reubenharry)\
**Post date:** [September 25, 2023, 10:32pm UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/1 "2023-09-25T22:32:08Z")

</div>

I’m trying to create a jupyter Bokeh demo in which a graph is updated in real time (e.g. via a loop) but at the same time, the updating depends on interactivity from a slider. So a simple example would be:

a random walk in 2D shown on a scatter plot, which updates every millisecond, in which the size of the random jumps is controlled by a slider.

I’ve found Bokeh tutorials showing separately how to do interactivity and live plotting ([https://github.com/bokeh/bokeh/tree/branch-3.3/examples/output/jupyter/push\_notebook](https://github.com/bokeh/bokeh/tree/branch-3.3/examples/output/jupyter/push_notebook)), but I’m having quite a lot of trouble combining them in a clean way. I was wondering if anyone knew of any simple example of this that I could work from, or simply had a suggestion of how to implement.

Thanks so much for your help!

Reuben

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [September 25, 2023, 11:12pm UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/2 "2023-09-25T23:12:14Z")

</div>

I would recommend not using `push_notebook` and instead embedding a Bokeh server app following this example:

[https://github.com/bokeh/bokeh/blob/branch-3.3/examples/server/api/notebook\_embed.ipynb](https://github.com/bokeh/bokeh/blob/branch-3.3/examples/server/api/notebook_embed.ipynb)

With a Bokeh server app you can mix and use standard Bokeh server periodic callbacks and event callbacks. `push_notebook` is an older API that pre-dates the Bokeh server by several years, and has various significant limitations in comparison. It is useful for exactly the sort of examples already in the repo, and not much beyond that.

---

<div class="post-metadata">

**Author:** ![reubenharry](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/reubenharry/32/6254_2.png) [@reubenharry](https://discourse.bokeh.org/u/reubenharry)\
**Post date:** [September 26, 2023, 12:37am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/3 "2023-09-26T00:37:20Z")

</div>

A follow up question.

In the linked example, which is very helpful, I see that the variable `source` can be mutated in a callback. However a new variable I define (eg. j = 0 on the line below the definition of `source`) cannot be without raising an error. Is there a good way to keep a state variable which isn’t a `ColumnDataSource`?

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [September 26, 2023, 3:53am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/4 "2023-09-26T03:53:42Z")

</div>

Since the entire `app` including callback functions is itself defined inside a function, you’d need to use the somewhat uncommon [`nonlocal` keyword](https://www.w3schools.com/python/ref_keyword_nonlocal.asp) in this instance.

There are potentially other ways to embed Bokeh apps in notebooks using different applications handler types that don’t involve nested functions. But I’m not sure they are especially better in any particular ways.

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [September 26, 2023, 4:03am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/5 "2023-09-26T04:03:11Z")

</div>

Actually, looking back at the relevant codepaths, I think you could define a class with a ` __call__ ` method that does the work of `modify_doc` and then pass an instance of that callable object to `show` and it would work. In that case, you could use instance vars e.g. `self.j` freely, which seems a little more commonplace than relying on `nonlocal`

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [September 26, 2023, 4:10am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/6 "2023-09-26T04:10:02Z")

</div>

Yes, here is an updated version from that example:

```python
class bkapp:  
    df = sea_surface_temperature.copy()

    def __init__ (self):
        self._theme_json = """
           attrs:
                figure:
                    background_fill_color: "#DDDDDD"
                    outline_line_color: white
                    toolbar_location: above
                    height: 500
                    width: 800
                Grid:
                    grid_line_dash: [6, 4]
                    grid_line_color: white
        """

    def callback(self, attr, old, new):
        if new == 0:
            data = self.df
        else:
            data = self.df.rolling('{0}D'.format(new)).mean()
        self.source.data = ColumnDataSource.from_df(data)

    def __call__ (self, doc):
        self.source = ColumnDataSource(data=self.df)
    
        plot = figure(x_axis_type='datetime', y_range=(0, 25),
                      y_axis_label='Temperature (Celsius)',
                      title="Sea Surface Temperature at 43.18, -70.43")
        plot.line('time', 'temperature', source=self.source)
    
        slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
        slider.on_change('value', self.callback)
    
        doc.add_root(column(slider, plot))

```

Then call with

```auto
show(bkapp()) # pass an instance to show

```

I’ll make an issue to add this version to the docs and “officially” support it.

Edit:

> <https://github.com/bokeh/bokeh/issues/13395>
>
> ref: https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/6?u=bryan
> …
> 
> While answering the above user question, it occurred to me that callable objects might be a much simpler/more straightforward way to express apps in notebooks that does not involve nested functions (and even potentially having to resort to \`nonlocal\` as in that question). 
> 
> The existing code want's to "tighten up" the types for \`show\`:
> 
> https://github.com/bokeh/bokeh/blob/bb1582ab7be57ac53baed5edae9ab28db4fe9495/src/bokeh/io/showing.py#L148
> 
> But I now think we should \*not\* do that, and explicitly support (test) with callable objects like the code in the referenced disussion, and even update the example to use this method.

---

<div class="post-metadata">

**Author:** ![reubenharry](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/reubenharry/32/6254_2.png) [@reubenharry](https://discourse.bokeh.org/u/reubenharry)\
**Post date:** [September 26, 2023, 11:51am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/7 "2023-09-26T11:51:50Z")

</div>

Thank you, that’s awesome! I really appreciate the help!

---

<div class="post-metadata">

**Author:** ![system](https://discourse-uploads.bokeh.org/original/2X/1/14eb24f9e10e4e9b78e3f10f66c04ffa96446e5a.svg) [@system](https://discourse.bokeh.org/u/system)\
**Post date:** [December 25, 2023, 11:52am UTC](https://discourse.bokeh.org/t/live-plot-with-interactivity/10890/8 "2023-12-25T11:52:47Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
