Bokeh server clarification

I’m struggling to understand how precisely the Bokeh server is supposed to work. Admittedly, my use case may be a little unique. I’m currently trying to find a back to embed plots in PyQt windows. That is, to generate separate plots and display them as a web view within a PyQt application.

I’ve attempted a couple ways of doing this. Mainly, by starting a Bokeh server when the PyQt application starts via the subprocess module (which listens for Qt close events in order to kill the server on exit). I then have a Line1D class that encapsulates a session so that I can have access to the generated plots in order to facilitate interactions between the user and the plot (e.g. propagating selection events to other, non-Bokeh data analysis functions). Here is a pared down version of the class:

process = subprocess.Popen(['bokeh', 'serve'])

class Line1D(EventDispatchMixin):
    def __init__(self):
        # Add a listener to the close application event so we can clean up the
        # Bokeh server we opened
        self.add_listener("on_application_close", self.close)

        x = np.linspace(0, 4*np.pi, 80)
        y = np.sin(x)

        p = figure(sizing_mode="stretch_both")
        r1 = p.line([0, 4*np.pi], [-1, 1], color="firebrick")
        r2 = p.line(x, y, color="navy", line_width=4)

        # open a session to keep our local document in sync with server
        self.session = push_session(curdoc())
        # self.html = autoload_server(None, session_id=self.session.id)
        self.url = "{}?bokeh-session-id={}".format(
            server_url_for_websocket_url(self.session._connection.url),
            _encode_query_param(self.session.id))
        print(self.url)

    def close(self):
        process.kill()

I would generate the url and store it within the class, however, the url gives nothing, i.e. the Bokeh output on the terminal looks reasonable, but the browser page is blank. The source does show that injection is correct, however. If I add a “self.session.show(p)” to the code above, I can get the plot to render both in the PyQt application window and, of course, the new browser window that’s opened up. But this is not ideal – I have no use for the browser window. How can I trigger whatever it is the “show” method does to render the plot, without having it auto-open a browser window?

I’m sure I’m doing something far from ideal in my view of how this should work. For one, fragments of mailing list posts and SO questions indicates that the recommended way to operate multiple rendered plots is to start a Bokeh server for each one. Is there a programmatic way to start and handle multiple Bokeh servers?

Any help/guidance would be greatly appreciated!

Thanks,
Nick

Hi Nick,

You are not adding anything to the document, so nothing is showing up. ClientSession.show adds the thing you pass to it as a convenience, if it isn't already in the document. You can do:

  curdoc().add_root(p)

Thanks,

Bryan

···

On Sep 26, 2016, at 1:08 PM, [email protected] wrote:

I'm struggling to understand how precisely the Bokeh server is supposed to work. Admittedly, my use case may be a little unique. I'm currently trying to find a back to embed plots in PyQt windows. That is, to generate separate plots and display them as a web view within a PyQt application.

I've attempted a couple ways of doing this. Mainly, by starting a Bokeh server when the PyQt application starts via the subprocess module (which listens for Qt close events in order to kill the server on exit). I then have a Line1D class that encapsulates a session so that I can have access to the generated plots in order to facilitate interactions between the user and the plot (e.g. propagating selection events to other, non-Bokeh data analysis functions). Here is a pared down version of the class:

process = subprocess.Popen(['bokeh', 'serve'])

class Line1D(EventDispatchMixin):
    def __init__(self):
        # Add a listener to the close application event so we can clean up the
        # Bokeh server we opened
        self.add_listener("on_application_close", self.close)

        x = np.linspace(0, 4*np.pi, 80)
        y = np.sin(x)

        p = figure(sizing_mode="stretch_both")
        r1 = p.line([0, 4*np.pi], [-1, 1], color="firebrick")
        r2 = p.line(x, y, color="navy", line_width=4)

        # open a session to keep our local document in sync with server
        self.session = push_session(curdoc())
        # self.html = autoload_server(None, session_id=self.session.id)
        self.url = "{}?bokeh-session-id={}".format(
            server_url_for_websocket_url(self.session._connection.url),
            _encode_query_param(self.session.id))
        print(self.url)

    def close(self):
        process.kill()

I would generate the url and store it within the class, however, the url gives nothing, i.e. the Bokeh output on the terminal looks reasonable, but the browser page is blank. The source does show that injection is correct, however. If I add a "self.session.show(p)" to the code above, I can get the plot to render both in the PyQt application window and, of course, the new browser window that's opened up. But this is not ideal -- I have no use for the browser window. How can I trigger whatever it is the "show" method does to render the plot, without having it auto-open a browser window?

I'm sure I'm doing something far from ideal in my view of how this should work. For one, fragments of mailing list posts and SO questions indicates that the recommended way to operate multiple rendered plots is to start a Bokeh server for each one. Is there a programmatic way to start and handle multiple Bokeh servers?

Any help/guidance would be greatly appreciated!

Thanks,
Nick

--
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/0ef58a1d-ef57-485b-b436-f92d6cd9eccd%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Thanks Bryan, that solved that problem. However, I can’t seem to figure out the server question:

… fragments of mailing list posts and SO questions indicates that the recommended way to operate multiple rendered plots is to start a Bokeh server for each one. Is there a programmatic way to start and handle multiple Bokeh servers?

Right now, I just start a single server, and keep creating new figures, generating new urls by using “curdoc().add_root(p)” and “push_session(curdoc())”. But a few strange things happen. One, the labels on the previous plots disappear. The second thing is that the webpages get slower to initially render (but are fine after rendering).

  1. Is there a solution to the missing labels issue?
  2. Is this the most appropriate way to be generating separate plots?
  3. If this isn’t the most appropriate way, and creating a Bokeh server for each separate plot is the correct way, how do I manage these severs / how do I dictate that a particular plot object be rendered by a particular server?
    Thanks again for your guidance,

Nick

Should I be

···

On Saturday, October 1, 2016 at 10:02:23 PM UTC-4, Bryan Van de ven wrote:

Hi Nick,

You are not adding anything to the document, so nothing is showing up. ClientSession.show adds the thing you pass to it as a convenience, if it isn’t already in the document. You can do:

    curdoc().add_root(p)

Thanks,

Bryan

On Sep 26, 2016, at 1:08 PM, [email protected] wrote:

I’m struggling to understand how precisely the Bokeh server is supposed to work. Admittedly, my use case may be a little unique. I’m currently trying to find a back to embed plots in PyQt windows. That is, to generate separate plots and display them as a web view within a PyQt application.

I’ve attempted a couple ways of doing this. Mainly, by starting a Bokeh server when the PyQt application starts via the subprocess module (which listens for Qt close events in order to kill the server on exit). I then have a Line1D class that encapsulates a session so that I can have access to the generated plots in order to facilitate interactions between the user and the plot (e.g. propagating selection events to other, non-Bokeh data analysis functions). Here is a pared down version of the class:

process = subprocess.Popen([‘bokeh’, ‘serve’])

class Line1D(EventDispatchMixin):

def __init__(self):
    # Add a listener to the close application event so we can clean up the
    # Bokeh server we opened
    self.add_listener("on_application_close", self.close)
    x = np.linspace(0, 4*np.pi, 80)
    y = np.sin(x)
    p = figure(sizing_mode="stretch_both")
    r1 = p.line([0, 4*np.pi], [-1, 1], color="firebrick")
    r2 = p.line(x, y, color="navy", line_width=4)
    # open a session to keep our local document in sync with server
    self.session = push_session(curdoc())
    # self.html = autoload_server(None, session_id=[self.session.id](http://self.session.id))
    self.url = "{}?bokeh-session-id={}".format(
        server_url_for_websocket_url(self.session._connection.url),
        _encode_query_param([self.session.id](http://self.session.id)))
    print(self.url)
def close(self):
    process.kill()

I would generate the url and store it within the class, however, the url gives nothing, i.e. the Bokeh output on the terminal looks reasonable, but the browser page is blank. The source does show that injection is correct, however. If I add a “self.session.show(p)” to the code above, I can get the plot to render both in the PyQt application window and, of course, the new browser window that’s opened up. But this is not ideal – I have no use for the browser window. How can I trigger whatever it is the “show” method does to render the plot, without having it auto-open a browser window?

I’m sure I’m doing something far from ideal in my view of how this should work. For one, fragments of mailing list posts and SO questions indicates that the recommended way to operate multiple rendered plots is to start a Bokeh server for each one. Is there a programmatic way to start and handle multiple Bokeh servers?

Any help/guidance would be greatly appreciated!

Thanks,

Nick


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/0ef58a1d-ef57-485b-b436-f92d6cd9eccd%40continuum.io.

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