What is the best way to stream text?

I’m trying to determine what the best way to stream text updates to a figure via bokeh server. I’m currently streaming text updates via ColumnDataSource, but since the text is not first cleared before updating, it becomes unreadable (as you would expect).

Here is a self contained example (with some unused imports)…

Thanks,

Nick

from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource, show
from bokeh.models.tickers import FixedTicker
import bokeh.models.glyphs as glyphs

import numpy as np
import matplotlib.pyplot as plt

class random_integration(object):
def init(self):
self.x = np.arange(100)
self.y = sorted(np.random.randn(100))
self.counter = 0.
self.text = [‘Integration Number: {0:03.0f}’.format(self.counter)]

def integrate_foward(self):
    self.x = np.arange(100)
    self.y = sorted(np.random.randn(100))        
    self.counter += 1        
    self.text = randi.text

randi = random_integration()
def make_document(doc):

def update():
    randi.integrate_foward()
   
    # Set up model data for streaming
    new_data={}
    new_data['x']=randi.x
    new_data['y']=randi.y
    source.stream(new_data, rollover = 100)
   
    # Set up text data for streaming
    text_data=dict(
        x=[50],
        y=[-2],
        text=['Iteration Number: {0:03.0f}'.format(randi.counter)]
    )
    text_source.stream(text_data,rollover = 100)

# intialize the figure
p = figure(
    plot_width=500,
    plot_height=600,
    x_range = [0, 100],
    y_range = [-3, 3],
    y_axis_type="linear",
)

# ColumnDataSources give us a nice way to update the data quickly in the plot
source = ColumnDataSource(
    data=dict(
        x=randi.x,
        y=randi.y,
    )
)
text_source=ColumnDataSource(
    data=dict(
        x=[50],
        y=[-2],
        text=randi.text
    )
)

# This is the line that will be updated
p.line(x = 'x', y = 'y',source = source, line_width = 2, legend = 'Random CDF')

# Add a text renderer
p.text(x=50, y=-2, text='text', text_color='black', text_font_size="10pt",
       text_baseline="middle", text_align="center",source = text_source)
   
doc.title = "Random Distribution"
doc.add_root(p)

doc.add_periodic_callback(update, 100)

apps = {’/’: Application(FunctionHandler(make_document))}

server = Server(apps, port=5000)
server.start()

``

Solution
FYI for anyone else running into this issue, rollover should be set to 1 when streaming “1” text data point.

i.e.

text_source.stream(text_data,rollover = 1)

···

On Tuesday, June 26, 2018 at 2:41:11 PM UTC-4, Nicholas Schiraldi wrote:

I’m trying to determine what the best way to stream text updates to a figure via bokeh server. I’m currently streaming text updates via ColumnDataSource, but since the text is not first cleared before updating, it becomes unreadable (as you would expect).

Here is a self contained example (with some unused imports)…

Thanks,

Nick

from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource, show
from bokeh.models.tickers import FixedTicker
import bokeh.models.glyphs as glyphs

import numpy as np
import matplotlib.pyplot as plt

class random_integration(object):
def init(self):
self.x = np.arange(100)
self.y = sorted(np.random.randn(100))
self.counter = 0.
self.text = [‘Integration Number: {0:03.0f}’.format(self.counter)]

def integrate_foward(self):
    self.x = np.arange(100)
    self.y = sorted(np.random.randn(100))        
    self.counter += 1        
    self.text = randi.text

randi = random_integration()
def make_document(doc):

def update():
    randi.integrate_foward()
   
    # Set up model data for streaming
    new_data={}
    new_data['x']=randi.x
    new_data['y']=randi.y
    source.stream(new_data, rollover = 100)
   
    # Set up text data for streaming
    text_data=dict(
        x=[50],
        y=[-2],
        text=['Iteration Number: {0:03.0f}'.format(randi.counter)]
    )
    text_source.stream(text_data,rollover = 100)

# intialize the figure
p = figure(
    plot_width=500,
    plot_height=600,
    x_range = [0, 100],
    y_range = [-3, 3],
    y_axis_type="linear",
)

# ColumnDataSources give us a nice way to update the data quickly in the plot
source = ColumnDataSource(
    data=dict(
        x=randi.x,
        y=randi.y,
    )
)
text_source=ColumnDataSource(
    data=dict(
        x=[50],
        y=[-2],
        text=randi.text
    )
)

# This is the line that will be updated
p.line(x = 'x', y = 'y',source = source, line_width = 2, legend = 'Random CDF')

# Add a text renderer
p.text(x=50, y=-2, text='text', text_color='black', text_font_size="10pt",
       text_baseline="middle", text_align="center",source = text_source)
   
doc.title = "Random Distribution"
doc.add_root(p)


doc.add_periodic_callback(update, 100)

apps = {’/’: Application(FunctionHandler(make_document))}

server = Server(apps, port=5000)
server.start()

``

Hi,

I feel compelled to add that the .stream API is for efficiently adding one (or a few) points to an already existing large data source, without having to re-send all the data needlessly. If your column only has 1 item to begin with, and you only want to update that 1 item, there is no reason to use .stream at all, just send the entire new (tiny) .data property.

Thanks,

Bryan

···

On Jul 17, 2018, at 08:06, Nicholas Schiraldi [email protected] wrote:

Solution
FYI for anyone else running into this issue, rollover should be set to 1 when streaming “1” text data point.

i.e.

text_source.stream(text_data,rollover = 1)

On Tuesday, June 26, 2018 at 2:41:11 PM UTC-4, Nicholas Schiraldi wrote:

I’m trying to determine what the best way to stream text updates to a figure via bokeh server. I’m currently streaming text updates via ColumnDataSource, but since the text is not first cleared before updating, it becomes unreadable (as you would expect).

Here is a self contained example (with some unused imports)…

Thanks,

Nick

from bokeh.server.server import Server
from bokeh.application import Application
from bokeh.application.handlers.function import FunctionHandler
from bokeh.plotting import figure, ColumnDataSource, show
from bokeh.models.tickers import FixedTicker
import bokeh.models.glyphs as glyphs

import numpy as np
import matplotlib.pyplot as plt

class random_integration(object):
def init(self):
self.x = np.arange(100)
self.y = sorted(np.random.randn(100))
self.counter = 0.
self.text = [‘Integration Number: {0:03.0f}’.format(self.counter)]

def integrate_foward(self):
    self.x = np.arange(100)
    self.y = sorted(np.random.randn(100))        
    self.counter += 1        
    self.text = randi.text

randi = random_integration()
def make_document(doc):

def update():
    randi.integrate_foward()
    
    # Set up model data for streaming
    new_data={}
    new_data['x']=randi.x
    new_data['y']=randi.y
    source.stream(new_data, rollover = 100)
    
    # Set up text data for streaming
    text_data=dict(
        x=[50],
        y=[-2],
        text=['Iteration Number: {0:03.0f}'.format(randi.counter)]
    )
    text_source.stream(text_data,rollover = 100)

# intialize the figure
p = figure(
    plot_width=500,
    plot_height=600,
    x_range = [0, 100],
    y_range = [-3, 3],
    y_axis_type="linear",
)

# ColumnDataSources give us a nice way to update the data quickly in the plot
source = ColumnDataSource(
    data=dict(
        x=randi.x,
        y=randi.y,
    )
)
text_source=ColumnDataSource(
    data=dict(
        x=[50],
        y=[-2],
        text=randi.text
    )
)

# This is the line that will be updated
p.line(x = 'x', y = 'y',source = source, line_width = 2, legend = 'Random CDF')

# Add a text renderer
p.text(x=50, y=-2, text='text', text_color='black', text_font_size="10pt",
       text_baseline="middle", text_align="center",source = text_source)
    
doc.title = "Random Distribution"
doc.add_root(p)


doc.add_periodic_callback(update, 100)

apps = {’/’: Application(FunctionHandler(make_document))}

server = Server(apps, port=5000)
server.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/365c3b5f-8537-4be4-9feb-217cb67c5501%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.