Adding lines to plot on-the-fly causes flickering

I am trying to add lines to a blank plot on-the-fly. I am planning on creating these lines once in a periodic callback as worker hosts come online. However, when I do this, the lines continue to flicker almost like the lines are being replotted continuously. I have prototyped this behavior in the following minimal example which is also attached. Please let me know of a way to be able to add lines to a plot on-the-fly without knowing them all upfront.

Thanks!

main.py (941 Bytes)

···

“”“Main module for memory app.
“””

import bokeh.io
import bokeh.layouts
import bokeh.models
import bokeh.plotting

DOC = bokeh.io.curdoc()

def memory_plot():

"""Creates the memory plot.
"""

plot = bokeh.plotting.figure()
plot.xaxis.axis_label = "Time"
plot.yaxis.axis_label = "Memory [MiB]"

return plot

PLOT = memory_plot()

LAYOUT = bokeh.layouts.row([PLOT])

SOURCES = {}

def memory_update():

"""Streams data to memory plot.
"""

for i in range(5):

    if str(i) not in SOURCES:

        print("Creating line", i)

        source = bokeh.models.ColumnDataSource(
            data={'time': [], 'memory': []})
        PLOT.line('time', 'memory', source=source)
        data = {'time': [0.0, 1.0], 'memory': [0.0, 2.0*(i+1.0)]}
        source.stream(data, 50)
        SOURCES[str(i)] = source

DOC.add_periodic_callback(memory_update, 500)

DOC.add_root(LAYOUT)

Hi,

The typical pattern is to create all the plots and renderers and data sources up front (i.e. *not* in the periodic callback) and then use the callback to *update* the existing data sources (which causes the plots and renderers to update accordingly). Your current code is creating and transmitting five new line renderers and data sources every half second. That is probably not what you intend, if you are using stream (which is expressly useful for updating existing data sources, i.e, for *not* having to create and send all the data).

You might want to start with this example as a template to study:

  https://github.com/bokeh/bokeh/blob/master/examples/app/ohlc/main.py

Thanks,

Bryan

···

On Nov 4, 2016, at 8:16 AM, bherman <[email protected]> wrote:

I am trying to add lines to a blank plot on-the-fly. I am planning on creating these lines once in a periodic callback as worker hosts come online. However, when I do this, the lines continue to flicker almost like the lines are being replotted continuously. I have prototyped this behavior in the following minimal example which is also attached. Please let me know of a way to be able to add lines to a plot on-the-fly without knowing them all upfront.

Thanks!

-------------------------------------------------------------------

"""Main module for memory app.
"""

import bokeh.io
import bokeh.layouts
import bokeh.models
import bokeh.plotting

DOC = bokeh.io.curdoc()

def memory_plot():

    """Creates the memory plot.
    """

    plot = bokeh.plotting.figure()
    plot.xaxis.axis_label = "Time"
    plot.yaxis.axis_label = "Memory [MiB]"

    return plot

PLOT = memory_plot()

LAYOUT = bokeh.layouts.row([PLOT])

SOURCES = {}

def memory_update():

    """Streams data to memory plot.
    """

    for i in range(5):

        if str(i) not in SOURCES:

            print("Creating line", i)

            source = bokeh.models.ColumnDataSource(
                data={'time': , 'memory': })
            PLOT.line('time', 'memory', source=source)
            data = {'time': [0.0, 1.0], 'memory': [0.0, 2.0*(i+1.0)]}
            source.stream(data, 50)
            SOURCES[str(i)] = source

DOC.add_periodic_callback(memory_update, 500)

DOC.add_root(LAYOUT)

--
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/62b645b6-f4d2-41b8-8fd0-e4b0ea10263d%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<main.py>

I should clarify: I am suggesting adding all the potential line renderers and *empty* data sources up front, that will result in an empty plot (because the data sources are empty).

Thanks,

Bryan

···

On Nov 4, 2016, at 11:14 AM, Bryan Van de Ven <[email protected]> wrote:

Hi,

The typical pattern is to create all the plots and renderers and data sources up front (i.e. *not* in the periodic callback) and then use the callback to *update* the existing data sources (which causes the plots and renderers to update accordingly). Your current code is creating and transmitting five new line renderers and data sources every half second. That is probably not what you intend, if you are using stream (which is expressly useful for updating existing data sources, i.e, for *not* having to create and send all the data).

You might want to start with this example as a template to study:

  https://github.com/bokeh/bokeh/blob/master/examples/app/ohlc/main.py

Thanks,

Bryan

On Nov 4, 2016, at 8:16 AM, bherman <[email protected]> wrote:

I am trying to add lines to a blank plot on-the-fly. I am planning on creating these lines once in a periodic callback as worker hosts come online. However, when I do this, the lines continue to flicker almost like the lines are being replotted continuously. I have prototyped this behavior in the following minimal example which is also attached. Please let me know of a way to be able to add lines to a plot on-the-fly without knowing them all upfront.

Thanks!

-------------------------------------------------------------------

"""Main module for memory app.
"""

import bokeh.io
import bokeh.layouts
import bokeh.models
import bokeh.plotting

DOC = bokeh.io.curdoc()

def memory_plot():

   """Creates the memory plot.
   """

   plot = bokeh.plotting.figure()
   plot.xaxis.axis_label = "Time"
   plot.yaxis.axis_label = "Memory [MiB]"

   return plot

PLOT = memory_plot()

LAYOUT = bokeh.layouts.row([PLOT])

SOURCES = {}

def memory_update():

   """Streams data to memory plot.
   """

   for i in range(5):

       if str(i) not in SOURCES:

           print("Creating line", i)

           source = bokeh.models.ColumnDataSource(
               data={'time': , 'memory': })
           PLOT.line('time', 'memory', source=source)
           data = {'time': [0.0, 1.0], 'memory': [0.0, 2.0*(i+1.0)]}
           source.stream(data, 50)
           SOURCES[str(i)] = source

DOC.add_periodic_callback(memory_update, 500)

DOC.add_root(LAYOUT)

--
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/62b645b6-f4d2-41b8-8fd0-e4b0ea10263d%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<main.py>

All that said, this seems like a bug, so I'd encourage yo uto make an issue with this code on the issue tracker.

Thanks,

Bryan

···

On Nov 4, 2016, at 11:23 AM, Bryan Van de Ven <[email protected]> wrote:

I should clarify: I am suggesting adding all the potential line renderers and *empty* data sources up front, that will result in an empty plot (because the data sources are empty).

Thanks,

Bryan

On Nov 4, 2016, at 11:14 AM, Bryan Van de Ven <[email protected]> wrote:

Hi,

The typical pattern is to create all the plots and renderers and data sources up front (i.e. *not* in the periodic callback) and then use the callback to *update* the existing data sources (which causes the plots and renderers to update accordingly). Your current code is creating and transmitting five new line renderers and data sources every half second. That is probably not what you intend, if you are using stream (which is expressly useful for updating existing data sources, i.e, for *not* having to create and send all the data).

You might want to start with this example as a template to study:

  https://github.com/bokeh/bokeh/blob/master/examples/app/ohlc/main.py

Thanks,

Bryan

On Nov 4, 2016, at 8:16 AM, bherman <[email protected]> wrote:

I am trying to add lines to a blank plot on-the-fly. I am planning on creating these lines once in a periodic callback as worker hosts come online. However, when I do this, the lines continue to flicker almost like the lines are being replotted continuously. I have prototyped this behavior in the following minimal example which is also attached. Please let me know of a way to be able to add lines to a plot on-the-fly without knowing them all upfront.

Thanks!

-------------------------------------------------------------------

"""Main module for memory app.
"""

import bokeh.io
import bokeh.layouts
import bokeh.models
import bokeh.plotting

DOC = bokeh.io.curdoc()

def memory_plot():

  """Creates the memory plot.
  """

  plot = bokeh.plotting.figure()
  plot.xaxis.axis_label = "Time"
  plot.yaxis.axis_label = "Memory [MiB]"

  return plot

PLOT = memory_plot()

LAYOUT = bokeh.layouts.row([PLOT])

SOURCES = {}

def memory_update():

  """Streams data to memory plot.
  """

  for i in range(5):

      if str(i) not in SOURCES:

          print("Creating line", i)

          source = bokeh.models.ColumnDataSource(
              data={'time': , 'memory': })
          PLOT.line('time', 'memory', source=source)
          data = {'time': [0.0, 1.0], 'memory': [0.0, 2.0*(i+1.0)]}
          source.stream(data, 50)
          SOURCES[str(i)] = source

DOC.add_periodic_callback(memory_update, 500)

DOC.add_root(LAYOUT)

--
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/62b645b6-f4d2-41b8-8fd0-e4b0ea10263d%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<main.py>

Though, it might be related to this known issue:

  multiple model sync in one callback can fail · Issue #5416 · bokeh/bokeh · GitHub

Bryan

···

On Nov 4, 2016, at 11:23 AM, Bryan Van de Ven <[email protected]> wrote:

I should clarify: I am suggesting adding all the potential line renderers and *empty* data sources up front, that will result in an empty plot (because the data sources are empty).

Thanks,

Bryan

On Nov 4, 2016, at 11:14 AM, Bryan Van de Ven <[email protected]> wrote:

Hi,

The typical pattern is to create all the plots and renderers and data sources up front (i.e. *not* in the periodic callback) and then use the callback to *update* the existing data sources (which causes the plots and renderers to update accordingly). Your current code is creating and transmitting five new line renderers and data sources every half second. That is probably not what you intend, if you are using stream (which is expressly useful for updating existing data sources, i.e, for *not* having to create and send all the data).

You might want to start with this example as a template to study:

  https://github.com/bokeh/bokeh/blob/master/examples/app/ohlc/main.py

Thanks,

Bryan

On Nov 4, 2016, at 8:16 AM, bherman <[email protected]> wrote:

I am trying to add lines to a blank plot on-the-fly. I am planning on creating these lines once in a periodic callback as worker hosts come online. However, when I do this, the lines continue to flicker almost like the lines are being replotted continuously. I have prototyped this behavior in the following minimal example which is also attached. Please let me know of a way to be able to add lines to a plot on-the-fly without knowing them all upfront.

Thanks!

-------------------------------------------------------------------

"""Main module for memory app.
"""

import bokeh.io
import bokeh.layouts
import bokeh.models
import bokeh.plotting

DOC = bokeh.io.curdoc()

def memory_plot():

  """Creates the memory plot.
  """

  plot = bokeh.plotting.figure()
  plot.xaxis.axis_label = "Time"
  plot.yaxis.axis_label = "Memory [MiB]"

  return plot

PLOT = memory_plot()

LAYOUT = bokeh.layouts.row([PLOT])

SOURCES = {}

def memory_update():

  """Streams data to memory plot.
  """

  for i in range(5):

      if str(i) not in SOURCES:

          print("Creating line", i)

          source = bokeh.models.ColumnDataSource(
              data={'time': , 'memory': })
          PLOT.line('time', 'memory', source=source)
          data = {'time': [0.0, 1.0], 'memory': [0.0, 2.0*(i+1.0)]}
          source.stream(data, 50)
          SOURCES[str(i)] = source

DOC.add_periodic_callback(memory_update, 500)

DOC.add_root(LAYOUT)

--
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/62b645b6-f4d2-41b8-8fd0-e4b0ea10263d%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<main.py>