How to plot streaming data real-time in Jupyter notebook

I’m trying to create a simple oscilloscope that shows a running FFT of audio data, sampled at 44100 Hz. Unfortunately, the push_notebook function takes too long to refresh the plot. Setting my input length to 256 samples, push_notebook takes around 1-5 ms. The time varies between runs, but is consistent in the same run. Not sure why that would be.

I need it to be less than 256/44100 (about 6 microseconds). Is this even possible with Bokeh?

from bokeh.io import push_notebook, show, output_notebook

from bokeh.layouts import row

from bokeh.plotting import figure

from bokeh.models.annotations import Title

output_notebook()

from numpy import fft, linspace

from time import time

class PlotFFT(object):

def init(self, axis_type, axis_lims):

self._line = None

self._fig = None

self._handle = None

self._axis_type = axis_type

self._axis_lims = axis_lims

def plot(self, data, fs, timestamp):

f = linspace(-fs/2, fs/2, len(data))

X = abs(fft.fftshift(fft.fft(data)))

if self._handle is None:

self._fig = figure(

plot_width=500,

plot_height=300,

y_range=self._axis_lims,

y_axis_type=self._axis_type,

title=“Time: {} seconds”.format(timestamp))

self._line = self._fig.line(f, X)

self._handle = show(self._fig, notebook_handle=True)

else:

self._line.data_source.data[‘y’] = X

self._fig.title.text=“Time: {} seconds”.format(timestamp)

start = time()

push_notebook(handle=self._handle)

print(“Elapsed: {}”.format(time() - start))

``

Hi,

The original implementation of push_notebook suffered many deficiencies. Please try dev build "0.12.10dev1" or newer, which has a completely new implementation of push_notebook based on the standard bokeh server protocol, including the recent efficient binary array transport work:

  https://bokeh.pydata.org/en/latest/docs/installation.html#developer-builds

Thanks,

Bryan

···

On Sep 25, 2017, at 22:14, [email protected] wrote:

I'm trying to create a simple oscilloscope that shows a running FFT of audio data, sampled at 44100 Hz. Unfortunately, the push_notebook function takes too long to refresh the plot. Setting my input length to 256 samples, push_notebook takes around 1-5 ms. The time varies between runs, but is consistent in the same run. Not sure why that would be.

I need it to be less than 256/44100 (about 6 microseconds). Is this even possible with Bokeh?

from bokeh.io import push_notebook, show, output_notebook
from bokeh.layouts import row
from bokeh.plotting import figure
from bokeh.models.annotations import Title
output_notebook()

from numpy import fft, linspace
from time import time

class PlotFFT(object):
    
    def __init__(self, axis_type, axis_lims):
        self._line = None
        self._fig = None
        self._handle = None
        self._axis_type = axis_type
        self._axis_lims = axis_lims

    def plot(self, data, fs, timestamp):
        f = linspace(-fs/2, fs/2, len(data))
        X = abs(fft.fftshift(fft.fft(data)))
        if self._handle is None:
            self._fig = figure(
                plot_width=500,
                plot_height=300,
                y_range=self._axis_lims,
                y_axis_type=self._axis_type,
                title="Time: {} seconds".format(timestamp))
            self._line = self._fig.line(f, X)
            self._handle = show(self._fig, notebook_handle=True)
        else:
            self._line.data_source.data['y'] = X
            self._fig.title.text="Time: {} seconds".format(timestamp)
            start = time()
            push_notebook(handle=self._handle)
            print("Elapsed: {}".format(time() - start))
        
--
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/51214f8c-51f6-4a9f-846b-9530fbf4bcde%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Actually, my numbers were a bit off in my original post. 10-50 ms for post_notebook, with 6 ms time resolution. Sleep deprivation.

Regardless, the dev release is much faster! 1-2 ms. The plotting doesn’t cause the audio playback to skip anymore. Thanks!

···

On Tuesday, September 26, 2017 at 12:32:45 AM UTC-4, Bryan Van de ven wrote:

Hi,

The original implementation of push_notebook suffered many deficiencies. Please try dev build “0.12.10dev1” or newer, which has a completely new implementation of push_notebook based on the standard bokeh server protocol, including the recent efficient binary array transport work:

    [https://bokeh.pydata.org/en/latest/docs/installation.html#developer-builds](https://bokeh.pydata.org/en/latest/docs/installation.html#developer-builds)

Thanks,

Bryan

On Sep 25, 2017, at 22:14, [email protected] wrote:

I’m trying to create a simple oscilloscope that shows a running FFT of audio data, sampled at 44100 Hz. Unfortunately, the push_notebook function takes too long to refresh the plot. Setting my input length to 256 samples, push_notebook takes around 1-5 ms. The time varies between runs, but is consistent in the same run. Not sure why that would be.

I need it to be less than 256/44100 (about 6 microseconds). Is this even possible with Bokeh?

from bokeh.io import push_notebook, show, output_notebook

from bokeh.layouts import row

from bokeh.plotting import figure

from bokeh.models.annotations import Title

output_notebook()

from numpy import fft, linspace

from time import time

class PlotFFT(object):

def __init__(self, axis_type, axis_lims):
    self._line = None
    self._fig = None
    self._handle = None
    self._axis_type = axis_type
    self._axis_lims = axis_lims
def plot(self, data, fs, timestamp):
    f = linspace(-fs/2, fs/2, len(data))
    X = abs(fft.fftshift(fft.fft(data)))
    if self._handle is None:
        self._fig = figure(
            plot_width=500,
            plot_height=300,
            y_range=self._axis_lims,
            y_axis_type=self._axis_type,
            title="Time: {} seconds".format(timestamp))
        self._line = self._fig.line(f, X)
        self._handle = show(self._fig, notebook_handle=True)
    else:
        self._line.data_source.data['y'] = X
        self._fig.title.text="Time: {} seconds".format(timestamp)
        start = time()
        push_notebook(handle=self._handle)
        print("Elapsed: {}".format(time() - start))


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/51214f8c-51f6-4a9f-846b-9530fbf4bcde%40continuum.io.

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