Add new lines to existing figure

I seem to be having an issue with adding new lines to an existing figure that’s being rendered. I’ve attempted two ways of doing this: (1) by simply calling the line method on the figure with a new ColumnDataSource; and (2) pre-composing the ColumnDataSource and all line GlyphRenders, and attempting to update the single ColumnDataSource with new information.

In both cases, I receive this error:

RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes

(Full trace here: http://pastebin.com/y6psNQDT)

Currently, this plot is being rendered in a PyQt QWebEngineView (QWebEngineView Class | Qt WebEngine 5.15.7), and the attempt to add a new line to the figure is done through a button callback in the Qt UI, which simple calls the “add_data” method. The setup is simple:

class BokehPlot(Plotter):
def init(self, *args, **kwargs):
super(BokehPlot, self).init(*args, **kwargs)

    self._fig = figure(sizing_mode='stretch_both')

    app = Application(FunctionHandler(
        lambda doc: doc.add_root(column(self._fig,
                                        sizing_mode='stretch_both'))))

    self._server = Server({'/': app}, io_loop=io_loop, port=next(ports))
    self._server.start()

    self.web_engine_view.setUrl(QUrl("http://localhost:{}/".format(
        self._server.port)))

def add_data(self, x, y):
    source = ColumnDataSource(data={'x': x, 'y': y})
    self._fit.plot('x', 'y', source=source)

I’m hoping that someone has come across this particular bug, and could let me know if it’s a limitation of using Qt and Bokeh together, or something else.

Thanks in advance,
Nick

Hi,

There's probably two things going on here. There were some bugs only jut recently fixed on master that had to go with adding new glyphs later after an app session was initialized. These should be fixed in the next release.

However, I think you also have another issue. Is it a Qt event that is triggering add_data directly? If so, that is absolutely problematic. The *only* safe way to modify a Bokeh document is from a Bokeh server callback that holds the necessary lock. For callbacks on Bokeh widgets, etc. this is all handled automatically. If you have events coming from elsewhere, you will need to "wrap" your document-modifying code in a call to add_next_tick_callback as described here:

  http://bokeh.pydata.org/en/latest/docs/user_guide/server.html#updating-from-threads

With this approach the "update a single CDS" approach you describe should work immediately. The "add a glyph" approach should work in the next release.

Thanks,

Bryan

···

On Mar 12, 2017, at 15:31, Nicholas Earl <[email protected]> wrote:

I seem to be having an issue with adding new lines to an existing figure that's being rendered. I've attempted two ways of doing this: (1) by simply calling the line method on the figure with a new ColumnDataSource; and (2) pre-composing the ColumnDataSource and all line GlyphRenders, and attempting to update the single ColumnDataSource with new information.

In both cases, I receive this error:

RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes

(Full trace here: http://pastebin.com/y6psNQDT\)

Currently, this plot is being rendered in a PyQt QWebEngineView (https://doc.qt.io/qt-5/qwebengineview.html\), and the attempt to add a new line to the figure is done through a button callback in the Qt UI, which simple calls the "add_data" method. The setup is simple:

class BokehPlot(Plotter):
    def __init__(self, *args, **kwargs):
        super(BokehPlot, self).__init__(*args, **kwargs)

        self._fig = figure(sizing_mode='stretch_both')

        app = Application(FunctionHandler(
            lambda doc: doc.add_root(column(self._fig,
                                            sizing_mode='stretch_both'))))

        self._server = Server({'/': app}, io_loop=io_loop, port=next(ports))
        self._server.start()

        self.web_engine_view.setUrl(QUrl("http://localhost:{}/".format(
            self._server.port)))

    def add_data(self, x, y):
        source = ColumnDataSource(data={'x': x, 'y': y})
        self._fit.plot('x', 'y', source=source)
    
I'm hoping that someone has come across this particular bug, and could let me know if it's a limitation of using Qt and Bokeh together, or something else.

Thanks in advance,
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/bd75d0be-a20b-4ae2-ae91-25358483d65e%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.