Replicated content in Bokeh interactive webpage

I am new to Bokeh and “web apps”. I am trying to create the following workflow:

WHAT I AM TRYING TO DO:

  1. In python create 2 Bokeh plots and a button. Show it in chrome browser.

  2. Look at plots in browser and click the “Done” button to get back to python

  3. Same as 1.

  4. Same as 2.

When I do this (1) and (2) work i.e. plots are shown and clicking DONE shuts down server and gets back to python script (test2() below). When I show the page again (please see code below) I get the following 2 plots + 1 button (inactive) + 2 plots + 1 button (active).

I would like to see just the 2 plots + 1 button (active) when I do 3) and 4).

QUESTIONS:

  1. What am I doing wrong to see replicated content?

  2. If I have a lot more plots, with around 20 curves per plot, to display on one page is my code/design below a reasonable choice?

Thanks for any help/insight.

Thanks

Prabu

import os

import os.path

import numpy as np

import subprocess

import time

import signal

from bokeh.client import push_session

from bokeh.models import ColumnDataSource

from bokeh.models.widgets import RadioButtonGroup

from bokeh.models.widgets import Button

from bokeh.plotting import curdoc

from bokeh.plotting import figure

from bokeh.layouts import layout

from bokeh.palettes import all_palettes

from bokeh.models import Legend

from bokeh.io import output_file

from bokeh.models import CheckboxGroup

class TestPage(object):

def init(self):

self._type = type

self._x = np.linspace(0, 10, 1000)

self._sinx = np.sin(self._x)

self._cosx = np.cos(self._x)

self._plots =

def show(self):

self._start_server()

self._create_doc()

def _create_doc(self):

Create oa bunch of copies of the same graphs

for i in range(2):

self._plots.append(figure(plot_width=1000,

plot_height=400,

toolbar_location=‘above’,

x_axis_label=‘Wavelengths (nm)’,

y_axis_label=‘Measurand’,

x_range=(0, 11),

y_range=(-3, 3)))

self._plots[i].line(self._x,

self._sinx,

color=‘red’,

line_width=2,

line_alpha=0.7)

self._plots[i].line(self._x,

self._cosx + 0.5,

color=‘green’,

line_width=2,

line_alpha=0.7)

A button to shut down and return to python

self._done_btn = Button(label=‘Done’)

self._done_btn.on_click(self._done_cb)

The layout

self._layout = layout([[p] for p in self._plots] + [[self._done_btn]])

self._session = push_session(curdoc())

self._session.show(self._layout, browser=‘google-chrome’)

self._session.loop_until_closed()

def _start_server(self):

Start the Bokeh server

args = [‘bokeh’, ‘serve’]

self._process = subprocess.Popen(args, shell=False)

time.sleep(1) # time to wait might be longer on other PC

print(‘Server pid: {}’.format(self._process.pid))

def _done_cb(self):

os.kill(self._process.pid, signal.SIGKILL)

self._process.terminate()

def test1():

TestPage().show()

def test2():

page1.show()

TestPage().show()

s = 0

for i in range(10):

s += i

TestPage().show()

page2.show()

if name == ‘main’:

test1()

test2()

I think I found a way to get this done (though I do not know if this is best practice). I added the following line as the very first line in _create_doc():

reset_output()

This got rid of the replicated content.

Thanks

Prabu

···

On Saturday, March 11, 2017 at 7:30:07 AM UTC-6, Prabu Ravindran wrote:

I am new to Bokeh and “web apps”. I am trying to create the following workflow:

WHAT I AM TRYING TO DO:

  1. In python create 2 Bokeh plots and a button. Show it in chrome browser.
  1. Look at plots in browser and click the “Done” button to get back to python
  1. Same as 1.
  1. Same as 2.

When I do this (1) and (2) work i.e. plots are shown and clicking DONE shuts down server and gets back to python script (test2() below). When I show the page again (please see code below) I get the following 2 plots + 1 button (inactive) + 2 plots + 1 button (active).

I would like to see just the 2 plots + 1 button (active) when I do 3) and 4).

QUESTIONS:

  1. What am I doing wrong to see replicated content?
  1. If I have a lot more plots, with around 20 curves per plot, to display on one page is my code/design below a reasonable choice?

Thanks for any help/insight.

Thanks

Prabu

import os

import os.path

import numpy as np

import subprocess

import time

import signal

from bokeh.client import push_session

from bokeh.models import ColumnDataSource

from bokeh.models.widgets import RadioButtonGroup

from bokeh.models.widgets import Button

from bokeh.plotting import curdoc

from bokeh.plotting import figure

from bokeh.layouts import layout

from bokeh.palettes import all_palettes

from bokeh.models import Legend

from bokeh.io import output_file

from bokeh.models import CheckboxGroup

class TestPage(object):

def init(self):

self._type = type

self._x = np.linspace(0, 10, 1000)

self._sinx = np.sin(self._x)

self._cosx = np.cos(self._x)

self._plots =

def show(self):

self._start_server()

self._create_doc()

def _create_doc(self):

Create oa bunch of copies of the same graphs

for i in range(2):

self._plots.append(figure(plot_width=1000,

plot_height=400,

toolbar_location=‘above’,

x_axis_label=‘Wavelengths (nm)’,

y_axis_label=‘Measurand’,

x_range=(0, 11),

y_range=(-3, 3)))

self._plots[i].line(self._x,

self._sinx,

color=‘red’,

line_width=2,

line_alpha=0.7)

self._plots[i].line(self._x,

self._cosx + 0.5,

color=‘green’,

line_width=2,

line_alpha=0.7)

A button to shut down and return to python

self._done_btn = Button(label=‘Done’)

self._done_btn.on_click(self._done_cb)

The layout

self._layout = layout([[p] for p in self._plots] + [[self._done_btn]])

self._session = push_session(curdoc())

self._session.show(self._layout, browser=‘google-chrome’)

self._session.loop_until_closed()

def _start_server(self):

Start the Bokeh server

args = [‘bokeh’, ‘serve’]

self._process = subprocess.Popen(args, shell=False)

time.sleep(1) # time to wait might be longer on other PC

print(‘Server pid: {}’.format(self._process.pid))

def _done_cb(self):

os.kill(self._process.pid, signal.SIGKILL)

self._process.terminate()

def test1():

TestPage().show()

def test2():

page1.show()

TestPage().show()

s = 0

for i in range(10):

s += i

TestPage().show()

page2.show()

if name == ‘main’:

test1()

test2()

Hi,

First off, sure that is an ok way to solve your immediate problem. An alternative is to explicitly manage Document classes and create clean blank ones between sessions.

Hoever, I'd like to encourage you to consider pursuing a different approach that utilizes the bokeh server better. The "bokeh.client" API (with push_session) etc. is one I would actively dis-encourage most people from looking at most off the time. It's useful for testing (being able to connect to a server from python is very useful for that) and also may be necessary in a few specialized use-cases (though some of those may not need it anymore with recent feature additions).

The reason boils down to this: Using bokeh.client means explicitly managing sessions. And just like explicitly managing memory in a language like C is much more complicated and error prone than in a garbage collected language like Python, explicitly managing sessions makes things much more complicated and error prone as well. The main task of the bokeh server is to manage sessions. Use properly and it will take all that burden off your shoulders!

So, I'd direct you to this example:

  https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py

That demonstrates how to embed a bokeh server "programmatically" inside a script, so that the app can be run as a true bokeh server app with sessions managed by the server. This has numerous benefits:

* no need to clean up with reset_out or explicitly manage documents
* no need to muck with external process management
* no need to manage sessions by hand
* network traffic is halved (with bokeh.client the server is just a dumb relay)
* probably less code to write too

Thanks,

Bryan

···

On Mar 11, 2017, at 09:09, [email protected] wrote:

I think I found a way to get this done (though I do not know if this is best practice). I added the following line as the very first line in _create_doc():

reset_output()

This got rid of the replicated content.

Thanks
Prabu

On Saturday, March 11, 2017 at 7:30:07 AM UTC-6, Prabu Ravindran wrote:
I am new to Bokeh and "web apps". I am trying to create the following workflow:

WHAT I AM TRYING TO DO:
1) In python create 2 Bokeh plots and a button. Show it in chrome browser.
2) Look at plots in browser and click the "Done" button to get back to python
3) Same as 1.
4) Same as 2.

When I do this (1) and (2) work i.e. plots are shown and clicking DONE shuts down server and gets back to python script (test2() below). When I show the page again (please see code below) I get the following 2 plots + 1 button (inactive) + 2 plots + 1 button (active).

I would like to see just the 2 plots + 1 button (active) when I do 3) and 4).

QUESTIONS:
1) What am I doing wrong to see replicated content?
2) If I have a lot more plots, with around 20 curves per plot, to display on one page is my code/design below a reasonable choice?

Thanks for any help/insight.

Thanks
Prabu

import os
import os.path
import numpy as np
import subprocess
import time
import signal
from bokeh.client import push_session
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import RadioButtonGroup
from bokeh.models.widgets import Button
from bokeh.plotting import curdoc
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.palettes import all_palettes
from bokeh.models import Legend
from bokeh.io import output_file
from bokeh.models import CheckboxGroup

class TestPage(object):
    def __init__(self):
        self._type = type
        self._x = np.linspace(0, 10, 1000)
        self._sinx = np.sin(self._x)
        self._cosx = np.cos(self._x)
        self._plots =

    def show(self):
        self._start_server()
        self._create_doc()

    def _create_doc(self):
        # Create oa bunch of copies of the same graphs
        for i in range(2):
            self._plots.append(figure(plot_width=1000,
                                      plot_height=400,
                                      toolbar_location='above',
                                      x_axis_label='Wavelengths (nm)',
                                      y_axis_label='Measurand',
                                      x_range=(0, 11),
                                      y_range=(-3, 3)))
            self._plots[i].line(self._x,
                                self._sinx,
                                color='red',
                                line_width=2,
                                line_alpha=0.7)
            self._plots[i].line(self._x,
                                self._cosx + 0.5,
                                color='green',
                                line_width=2,
                                line_alpha=0.7)
        # A button to shut down and return to python
        self._done_btn = Button(label='Done')
        self._done_btn.on_click(self._done_cb)

        # The layout
        self._layout = layout([[p] for p in self._plots] + [[self._done_btn]])
        self._session = push_session(curdoc())
        self._session.show(self._layout, browser='google-chrome')
        self._session.loop_until_closed()

    def _start_server(self):
        # Start the Bokeh server
        args = ['bokeh', 'serve']
        self._process = subprocess.Popen(args, shell=False)
        time.sleep(1) # time to wait might be longer on other PC
        print('Server pid: {}'.format(self._process.pid))

    def _done_cb(self):
        os.kill(self._process.pid, signal.SIGKILL)
        # self._process.terminate()

def test1():
    TestPage().show()

def test2():
    # page1.show()
    TestPage().show()

    s = 0
    for i in range(10):
        s += i

    TestPage().show()
    # page2.show()

if __name__ == '__main__':
    # test1()
    test2()

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/62557d70-3f94-4651-a29c-1ceec71d00c4%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hi Bryan

Thanks a lot for the very informative reply. I will follow up on the pointers you have suggested.

Thanks to you and your team for awesome Bokeh.

Prabu

···

On Saturday, March 11, 2017 at 10:55:21 AM UTC-6, Bryan Van de ven wrote:

Hi,

First off, sure that is an ok way to solve your immediate problem. An alternative is to explicitly manage Document classes and create clean blank ones between sessions.

Hoever, I’d like to encourage you to consider pursuing a different approach that utilizes the bokeh server better. The “bokeh.client” API (with push_session) etc. is one I would actively dis-encourage most people from looking at most off the time. It’s useful for testing (being able to connect to a server from python is very useful for that) and also may be necessary in a few specialized use-cases (though some of those may not need it anymore with recent feature additions).

The reason boils down to this: Using bokeh.client means explicitly managing sessions. And just like explicitly managing memory in a language like C is much more complicated and error prone than in a garbage collected language like Python, explicitly managing sessions makes things much more complicated and error prone as well. The main task of the bokeh server is to manage sessions. Use properly and it will take all that burden off your shoulders!

So, I’d direct you to this example:

    [https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py](https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py)

That demonstrates how to embed a bokeh server “programmatically” inside a script, so that the app can be run as a true bokeh server app with sessions managed by the server. This has numerous benefits:

  • no need to clean up with reset_out or explicitly manage documents

  • no need to muck with external process management

  • no need to manage sessions by hand

  • network traffic is halved (with bokeh.client the server is just a dumb relay)

  • probably less code to write too

Thanks,

Bryan

On Mar 11, 2017, at 09:09, [email protected] wrote:

I think I found a way to get this done (though I do not know if this is best practice). I added the following line as the very first line in _create_doc():

reset_output()

This got rid of the replicated content.

Thanks

Prabu

On Saturday, March 11, 2017 at 7:30:07 AM UTC-6, Prabu Ravindran wrote:

I am new to Bokeh and “web apps”. I am trying to create the following workflow:

WHAT I AM TRYING TO DO:

  1. In python create 2 Bokeh plots and a button. Show it in chrome browser.
  1. Look at plots in browser and click the “Done” button to get back to python
  1. Same as 1.
  1. Same as 2.

When I do this (1) and (2) work i.e. plots are shown and clicking DONE shuts down server and gets back to python script (test2() below). When I show the page again (please see code below) I get the following 2 plots + 1 button (inactive) + 2 plots + 1 button (active).

I would like to see just the 2 plots + 1 button (active) when I do 3) and 4).

QUESTIONS:

  1. What am I doing wrong to see replicated content?
  1. If I have a lot more plots, with around 20 curves per plot, to display on one page is my code/design below a reasonable choice?

Thanks for any help/insight.

Thanks

Prabu

import os

import os.path

import numpy as np

import subprocess

import time

import signal

from bokeh.client import push_session

from bokeh.models import ColumnDataSource

from bokeh.models.widgets import RadioButtonGroup

from bokeh.models.widgets import Button

from bokeh.plotting import curdoc

from bokeh.plotting import figure

from bokeh.layouts import layout

from bokeh.palettes import all_palettes

from bokeh.models import Legend

from bokeh.io import output_file

from bokeh.models import CheckboxGroup

class TestPage(object):

def __init__(self):
    self._type = type
    self._x = np.linspace(0, 10, 1000)
    self._sinx = np.sin(self._x)
    self._cosx = np.cos(self._x)
    self._plots = []
def show(self):
    self._start_server()
    self._create_doc()
def _create_doc(self):
    # Create oa bunch of copies of the same graphs
    for i in range(2):
        self._plots.append(figure(plot_width=1000,
                                  plot_height=400,
                                  toolbar_location='above',
                                  x_axis_label='Wavelengths (nm)',
                                  y_axis_label='Measurand',
                                  x_range=(0, 11),
                                  y_range=(-3, 3)))
        self._plots[i].line(self._x,
                            self._sinx,
                            color='red',
                            line_width=2,
                            line_alpha=0.7)
        self._plots[i].line(self._x,
                            self._cosx + 0.5,
                            color='green',
                            line_width=2,
                            line_alpha=0.7)
    # A button to shut down and return to python
    self._done_btn = Button(label='Done')
    self._done_btn.on_click(self._done_cb)
    # The layout
    self._layout = layout([[p] for p in self._plots] + [[self._done_btn]])
    self._session = push_session(curdoc())
    self._session.show(self._layout, browser='google-chrome')
    self._session.loop_until_closed()
def _start_server(self):
    # Start the Bokeh server
    args = ['bokeh', 'serve']
    self._process = subprocess.Popen(args, shell=False)
    time.sleep(1) # time to wait might be longer on other PC
    print('Server pid: {}'.format(self._process.pid))
def _done_cb(self):
    os.kill(self._process.pid, signal.SIGKILL)
    # self._process.terminate()

def test1():

TestPage().show()

def test2():

# page1.show()
TestPage().show()
s = 0
for i in range(10):
    s += i
TestPage().show()
# page2.show()

if name == ‘main’:

# test1()
test2()


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/62557d70-3f94-4651-a29c-1ceec71d00c4%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Hello Bryan

I was able to close the server and restart it using the pointer you provided. Thanks.

I followed up on the pointers you provided (atleast I think I did) to try and do the following:

  1. Display a sequence of plots one at a time at the click of a next button/prev button.

  2. Each plot in the sequence has a different number of curves to show (but the xaxis values will be same).

I am seeing the first plot in the sequence. When I hit the next/prev button there is some change but the new plot does not show up in the figure. If it is not too much trouble, can you please point me in the right direction (again)? In the code attached there are 4 curves to plot. I want to show only the first curve in the first plot, hit the next button and the plot should show only the curves 2, 3 and 4 (i.e.not the first).

To run the code I do python3 spectrum_selector.py

Thanks a lot for your time,

Prabu

spectrum_selector.py (3.84 KB)

···

On Saturday, March 11, 2017 at 2:47:38 PM UTC-6, Prabu Ravindran wrote:

Hi Bryan

Thanks a lot for the very informative reply. I will follow up on the pointers you have suggested.

Thanks to you and your team for awesome Bokeh.

Prabu

On Saturday, March 11, 2017 at 10:55:21 AM UTC-6, Bryan Van de ven wrote:

Hi,

First off, sure that is an ok way to solve your immediate problem. An alternative is to explicitly manage Document classes and create clean blank ones between sessions.

Hoever, I’d like to encourage you to consider pursuing a different approach that utilizes the bokeh server better. The “bokeh.client” API (with push_session) etc. is one I would actively dis-encourage most people from looking at most off the time. It’s useful for testing (being able to connect to a server from python is very useful for that) and also may be necessary in a few specialized use-cases (though some of those may not need it anymore with recent feature additions).

The reason boils down to this: Using bokeh.client means explicitly managing sessions. And just like explicitly managing memory in a language like C is much more complicated and error prone than in a garbage collected language like Python, explicitly managing sessions makes things much more complicated and error prone as well. The main task of the bokeh server is to manage sessions. Use properly and it will take all that burden off your shoulders!

So, I’d direct you to this example:

    [https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py](https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py)

That demonstrates how to embed a bokeh server “programmatically” inside a script, so that the app can be run as a true bokeh server app with sessions managed by the server. This has numerous benefits:

  • no need to clean up with reset_out or explicitly manage documents

  • no need to muck with external process management

  • no need to manage sessions by hand

  • network traffic is halved (with bokeh.client the server is just a dumb relay)

  • probably less code to write too

Thanks,

Bryan

On Mar 11, 2017, at 09:09, [email protected] wrote:

I think I found a way to get this done (though I do not know if this is best practice). I added the following line as the very first line in _create_doc():

reset_output()

This got rid of the replicated content.

Thanks

Prabu

On Saturday, March 11, 2017 at 7:30:07 AM UTC-6, Prabu Ravindran wrote:

I am new to Bokeh and “web apps”. I am trying to create the following workflow:

WHAT I AM TRYING TO DO:

  1. In python create 2 Bokeh plots and a button. Show it in chrome browser.
  1. Look at plots in browser and click the “Done” button to get back to python
  1. Same as 1.
  1. Same as 2.

When I do this (1) and (2) work i.e. plots are shown and clicking DONE shuts down server and gets back to python script (test2() below). When I show the page again (please see code below) I get the following 2 plots + 1 button (inactive) + 2 plots + 1 button (active).

I would like to see just the 2 plots + 1 button (active) when I do 3) and 4).

QUESTIONS:

  1. What am I doing wrong to see replicated content?
  1. If I have a lot more plots, with around 20 curves per plot, to display on one page is my code/design below a reasonable choice?

Thanks for any help/insight.

Thanks

Prabu

import os

import os.path

import numpy as np

import subprocess

import time

import signal

from bokeh.client import push_session

from bokeh.models import ColumnDataSource

from bokeh.models.widgets import RadioButtonGroup

from bokeh.models.widgets import Button

from bokeh.plotting import curdoc

from bokeh.plotting import figure

from bokeh.layouts import layout

from bokeh.palettes import all_palettes

from bokeh.models import Legend

from bokeh.io import output_file

from bokeh.models import CheckboxGroup

class TestPage(object):

def __init__(self):
    self._type = type
    self._x = np.linspace(0, 10, 1000)
    self._sinx = np.sin(self._x)
    self._cosx = np.cos(self._x)
    self._plots = []
def show(self):
    self._start_server()
    self._create_doc()
def _create_doc(self):
    # Create oa bunch of copies of the same graphs
    for i in range(2):
        self._plots.append(figure(plot_width=1000,
                                  plot_height=400,
                                  toolbar_location='above',
                                  x_axis_label='Wavelengths (nm)',
                                  y_axis_label='Measurand',
                                  x_range=(0, 11),
                                  y_range=(-3, 3)))
        self._plots[i].line(self._x,
                            self._sinx,
                            color='red',
                            line_width=2,
                            line_alpha=0.7)
        self._plots[i].line(self._x,
                            self._cosx + 0.5,
                            color='green',
                            line_width=2,
                            line_alpha=0.7)
    # A button to shut down and return to python
    self._done_btn = Button(label='Done')
    self._done_btn.on_click(self._done_cb)
    # The layout
    self._layout = layout([[p] for p in self._plots] + [[self._done_btn]])
    self._session = push_session(curdoc())
    self._session.show(self._layout, browser='google-chrome')
    self._session.loop_until_closed()
def _start_server(self):
    # Start the Bokeh server
    args = ['bokeh', 'serve']
    self._process = subprocess.Popen(args, shell=False)
    time.sleep(1) # time to wait might be longer on other PC
    print('Server pid: {}'.format(self._process.pid))
def _done_cb(self):
    os.kill(self._process.pid, signal.SIGKILL)
    # self._process.terminate()

def test1():

TestPage().show()

def test2():

# page1.show()
TestPage().show()
s = 0
for i in range(10):
    s += i
TestPage().show()
# page2.show()

if name == ‘main’:

# test1()
test2()


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/62557d70-3f94-4651-a29c-1ceec71d00c4%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.