问题
I am displaying 2d data as images of varying shapes in a bokeh server, and therefore need to dynamically update not only the image's data source, but also its dw
, dh
, x
, and y
properties. In the dummy example below, these changes are made in a callback function which is connected to a Button
widget.
I've figured out that I need to access the glyph
attribute of the image's GlyphRenderer
object, and I can do so through its update()
method (see code). But the changes don't take effect until I click the toolbar's Reset button. I've noticed that the changes also mysteriously take effect the second time I activate the callback()
function. What is the proper way to make these changes?
import bokeh.plotting
import bokeh.models
import bokeh.layouts
import numpy as np
# set up the interface
fig1 = bokeh.plotting.figure(x_range=(0, 10), y_range=(0, 10))
im1 = fig1.image([], dw=5, dh=5)
button = bokeh.models.Button(label='scramble')
# add everything to the document
bokeh.plotting.curdoc().add_root(bokeh.layouts.column(button, fig1))
# define a callback and connect it
def callback():
# this always works:
im1.data_source.data = {'image': [np.random.random((100,100))]}
# these changes only take effect after pressing the "Reset"
# button, or after triggering this callback function twice:
im1.glyph.update(x=1, y=1, dw=9, dh=9)
button.on_click(callback)
回答1:
I don't immediately see why you code isn't work. I can suggest explicitly using a ColumnDataSource and linking all of the Image glyph properties to columns in that source. Then you should be able to update the source.data in a single line and have all of the updates apply.
Here's some incomplete sample code to suggest how to do that:
from bokeh.models import Image, ColumnDataSource
from bokeh.plotting import figure
# the plotting code
plot = figure()
source = ColumnDataSource(data=dict(image=[], x=[], y=[], dw=[], dh=[]))
image = Image(data='image', x='x', y='y', dw='dw', dh=dh)
plot.add_glyph(source, glyph=image)
# the callback
def callback():
source.data = {'image': [np.random.random((100,100))], 'x':[1], 'y':[1], 'dw':[9], 'dh':[9]}
button.on_click(callback)
来源:https://stackoverflow.com/questions/39986024/how-to-change-the-extent-and-position-of-an-existing-image-in-bokeh