Updating image or figure with new x,y,dw,dh

I’m wanting to be able to change the image in a figure based on new data the user selects. Using bokeh server.

Lets say I want to start my script with an empty figure:
simage = ColumnDataSource(x=,y=,image=)
p = figure(plot_width=512,plot_height=512)
p.image(image=‘image’,source=simage,x=0,y=0,dw=1,dh=1)

``

Now the user inputs a new file to upload data from (lets say with TextInput). I want the user to be able to switch files, which may have different data sizes. I know I need to update simage with the new data, but how do I update the image with the correct x,y,dw,dh, or the figure x_range and y_range?

f = np.load(‘data.npz’)
simage.data = dict(x=[f[‘x’]], y=[f[‘y’]], image=[f[‘image’]])
#??? How to update p???

``

OK, I have a working example that solves the problem. Please let me know if there is a more efficient way to do this:

from bokeh.plotting import figure,show, ColumnDataSource
from bokeh.models.widgets import TextInput,Select
from bokeh.plotting import curdoc
from bokeh.layouts import row, column
from bokeh.models.ranges import DataRange1d
import numpy as np

simage = ColumnDataSource(data=dict(x=,y=,dw=,dh=,image=))

def create_data(xsize,ysize):
global simage
x = np.arange(xsize)-xsize/2.
y = np.arange(ysize)-ysize/2.
image_data = np.random.rand(ysize,xsize)
simage.data = dict(x=[x[0]],y=[y[0]],dw=[x.max()-x.min()],dh=[y.max()-y.min()],image=[image_data])
return x,y,image_data

p = figure(plot_height=512,plot_width=512,x_range=(0,1),y_range=(0,1))
p.image(image=‘image’,source=simage,x=‘x’,y=‘y’,dw=‘dw’,dh=‘dh’)

dropselect = Select(value=‘1’,options=[‘1’,‘2’,‘3’],title=‘Select data set’)
def dropselect_update(attribute,old,new):
if new==‘1’:
xsize = 80; ysize = 182
elif new==‘2’:
xsize = 100; ysize = 100
else:
xsize = 140; ysize = 30
x,y,_ = create_data(xsize,ysize)
p.x_range.start = x.min(); p.x_range.end = x.max()
p.y_range.start = y.min(); p.y_range.end = y.max()

dropselect.on_change(‘value’,dropselect_update)

layout = row(dropselect,p)
curdoc().add_root(layout)

``

···

On Monday, February 13, 2017 at 3:39:06 PM UTC-5, [email protected] wrote:

I’m wanting to be able to change the image in a figure based on new data the user selects. Using bokeh server.

Lets say I want to start my script with an empty figure:
simage = ColumnDataSource(x=,y=,image=)
p = figure(plot_width=512,plot_height=512)
p.image(image=‘image’,source=simage,x=0,y=0,dw=1,dh=1)

``

Now the user inputs a new file to upload data from (lets say with TextInput). I want the user to be able to switch files, which may have different data sizes. I know I need to update simage with the new data, but how do I update the image with the correct x,y,dw,dh, or the figure x_range and y_range?

f = np.load(‘data.npz’)
simage.data = dict(x=[f[‘x’]], y=[f[‘y’]], image=[f[‘image’]])
#??? How to update p???

``

1 Like

Hmm, my one issue with this workflow is that the ResetTool resets to the initialized plot x_range and y_range of (0,1), instead of the updated start and end supplied in dropselect_update. I saw Github issue #5443 addresses this, but look not assigned yet. +1. Or guidance on a better approach for the below.

···

On Monday, February 13, 2017 at 4:56:21 PM UTC-5, [email protected] wrote:

OK, I have a working example that solves the problem. Please let me know if there is a more efficient way to do this:

from bokeh.plotting import figure,show, ColumnDataSource
from bokeh.models.widgets import TextInput,Select
from bokeh.plotting import curdoc
from bokeh.layouts import row, column
from bokeh.models.ranges import DataRange1d
import numpy as np

simage = ColumnDataSource(data=dict(x=,y=,dw=,dh=,image=))

def create_data(xsize,ysize):
global simage
x = np.arange(xsize)-xsize/2.
y = np.arange(ysize)-ysize/2.
image_data = np.random.rand(ysize,xsize)
simage.data = dict(x=[x[0]],y=[y[0]],dw=[x.max()-x.min()],dh=[y.max()-y.min()],image=[image_data])
return x,y,image_data

p = figure(plot_height=512,plot_width=512,x_range=(0,1),y_range=(0,1))
p.image(image=‘image’,source=simage,x=‘x’,y=‘y’,dw=‘dw’,dh=‘dh’)

dropselect = Select(value=‘1’,options=[‘1’,‘2’,‘3’],title=‘Select data set’)
def dropselect_update(attribute,old,new):
if new==‘1’:
xsize = 80; ysize = 182
elif new==‘2’:
xsize = 100; ysize = 100
else:
xsize = 140; ysize = 30
x,y,_ = create_data(xsize,ysize)
p.x_range.start = x.min(); p.x_range.end = x.max()
p.y_range.start = y.min(); p.y_range.end = y.max()

dropselect.on_change(‘value’,dropselect_update)

layout = row(dropselect,p)
curdoc().add_root(layout)

``

On Monday, February 13, 2017 at 3:39:06 PM UTC-5, [email protected] wrote:

I’m wanting to be able to change the image in a figure based on new data the user selects. Using bokeh server.

Lets say I want to start my script with an empty figure:
simage = ColumnDataSource(x=,y=,image=)
p = figure(plot_width=512,plot_height=512)
p.image(image=‘image’,source=simage,x=0,y=0,dw=1,dh=1)

``

Now the user inputs a new file to upload data from (lets say with TextInput). I want the user to be able to switch files, which may have different data sizes. I know I need to update simage with the new data, but how do I update the image with the correct x,y,dw,dh, or the figure x_range and y_range?

f = np.load(‘data.npz’)
simage.data = dict(x=[f[‘x’]], y=[f[‘y’]], image=[f[‘image’]])
#??? How to update p???

``

Setting all the values to be updated as data in columns in the data source, and then updating the data source, is the best solution, and the one I as going to recommend. Regarding the reset tool, for now the only option for different behavior would be to create your own custom reset tool a Bokeh extension:

This helps a lot, thank you!