Bokeh:在图像打印中实现自定义javascript

Bokeh:在图像打印中实现自定义javascript,javascript,python,bokeh,Javascript,Python,Bokeh,我试图结合博克的这两个例子: 这个想法似乎很简单。我想绘制第一个链接中显示的图像,然后使用交互式滑块改变正弦函数的频率: import numpy as np from bokeh.plotting import figure, show, output_file from bokeh.models import CustomJS, ColumnDataSource, Slider from bokeh.io import vform N = 10 x = np.linspace(0

我试图结合博克的这两个例子:

这个想法似乎很简单。我想绘制第一个链接中显示的图像,然后使用交互式滑块改变正弦函数的频率:

import numpy as np

from bokeh.plotting import figure, show, output_file
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.io import vform


N = 10

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

output_file("image.html", title="image.py example")

source = ColumnDataSource(data={'d': d, 'x': x, 'y': y})

p = figure(x_range=[0, 10], y_range=[0, 10])
p.image([source.data['d']], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11")

callback = CustomJS(args=dict(source=source), code="""
        var data = source.get('data');
        var f = cb_obj.get('value')
        x = data['x']
        y = data['y']
        d = data['d']
        for (i = 0; i < x.length; i++) {
            for (i = 0; i < x.length; i++){
                d[i][j] = Math.sin(f*x[i])*Math.cos(y[j])
        }
        source.trigger('change');
    """)

slider = Slider(start=0.1, end=4, value=1, step=.1, title="angular frequency", callback=callback)

layout = vform(slider, p)

show(layout)
我认为这不是将绘图正确附加到源对象的方式。我只是传递了一个数组,这解释了为什么当源代码更改时绘图不会更新,但我不确定图像函数的正确方法是什么。如果我将声明更改为:

p.image(['d'], x=[0], y=[0], dw=[10], dh=[10], source=source, palette="Spectral11")

它不能正确地绘制。我不确定这是语法问题还是更深层次的问题。任何指点都将不胜感激。提前谢谢

几天来,我一直在处理一个类似的问题。最后我成功了。首先,请注意ColumnDataSource函数中的方括号[]。该数据允许多个图像。因此,在回调函数中,您应该使用[0]来获取一个图像的数据。此外,在图像源中使用“x”和“y”与图像x=[0]和y[0]的位置冲突,因此我使用了xx和yy。我想提到的是,我从tobyhodges的一个示例中借用了代码:一种将滑块信息推送到已定义的回调函数的方法。代码如下:

import numpy as np
from bokeh.plotting import figure, show, output_file
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.io import vform

N = 100

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

output_file("image.html", title="image.py example")

source = ColumnDataSource(data={'d': [d], 'xx': [x], 'yy': [y]})

p = figure(x_range=[0, 10], y_range=[0, 10])
p.image(image="d", x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11",source=source)

callback = CustomJS(args=dict(source=source), code="""
        var xx = source.get('data')['xx'][0];
        var yy = source.get('data')['yy'][0];
        var d = source.get('data')['d'][0];
        var f = slider.get('value');
        for (var i = 0; i < xx.length; i++) {
            for (var j = 0; j < yy.length; j++){
                d[i][j] = Math.sin(f * xx[i]) * Math.cos(yy[j]);
            }
        }
        source.trigger('change');
    """)

slider = Slider(start=0.1, end=4, value=1, step=.1, title="angular frequency", callback=callback)
callback.args['slider'] = slider
layout = vform(slider, p)
show(layout)
bokeh版本0.12.4的更新:

import numpy as np
import bokeh
import bokeh.plotting

N = 100

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

source = bokeh.models.ColumnDataSource(
    data=dict(values=[d],x_vals=[x],y_vals=[y]))

p = bokeh.plotting.figure(plot_width=300, plot_height=300,
    x_range=[0, 10], y_range=[0, 10])
p.image(image='values', x=0, y=0, dw=10, dh=10, 
    palette="Spectral11", source=source)

callback = bokeh.models.CustomJS(args=dict(source=source), code="""
    var f = slider.value;
    var x = source.data['x_vals'][0];
    var y = source.data['y_vals'][0];
    var d = source.data['values'][0];
    for (var j = 0; j < y.length; j++){
        for (var i = 0; i < x.length; i++) {
            d[j*y.length + i] = Math.sin(f*x[i]) * Math.cos(f*y[j]);
        }
    }
    source.change.emit();
    """)

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1,
    title="angular frequency",callback=callback)
callback.args['slider'] = slider
layout = bokeh.models.layouts.Row(p,slider)

bokeh.io.output_notebook()
bokeh.io.show(layout)
更改:现在输出的是一个
Jupyter
笔记本。要获取html页面,只需遵循以前的版本。这个bokeh版本的新特性是:
JavaScript
上的数组现在是1D数组

import numpy as np
import bokeh
import bokeh.plotting

N = 100

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

source = bokeh.models.ColumnDataSource(data={'x': [x], 'y': [y]})

p = bokeh.plotting.figure(plot_width=300, plot_height=300,x_range=[0, 10], y_range=[0, 10])
im = p.image(image=[d], x=[0], y=[0], dw=[10], dh=[10], palette="Spectral11")

callback = bokeh.models.CustomJS(args=dict(source=source,im=im), code="""
        var x = source.data['x'][0];
        var y = source.data['y'][0];
        var image_source = im.data_source;
        var d = image_source.data['image'][0];
        var f = slider.value;
        for (var j = 0; j < y.length; j++){
            for (var i = 0; i < x.length; i++) {
                d[j*y.length + i] = Math.sin(f * x[i]) * Math.cos(f * y[j]);
            }
        }
        image_source.trigger('change');
    """)

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1,
                             title="angular frequency",callback=callback)
callback.args['slider'] = slider
layout = bokeh.models.layouts.Row(p,slider)

bokeh.io.output_notebook()
bokeh.io.show(layout)
将numpy导入为np
进口波基
导入bokeh.plotting
N=100
x=np.linspace(0,10,N)
y=np.linspace(0,10,N)
xx,yy=np.meshgrid(x,y)
d=np.sin(xx)*np.cos(yy)
source=bokeh.models.ColumnDataSource(数据={'x':[x],'y':[y]})
图(绘图宽度=300,绘图高度=300,x范围=[0,10],y范围=[0,10])
im=p.image(image=[d],x=[0],y=[0],dw=[10],dh=[10],palete=“Spectral11”)
callback=bokeh.models.CustomJS(args=dict(source=source,im=im),code=”“”
var x=源数据['x'][0];
变量y=源数据['y'][0];
var image\u source=im.data\u source;
var d=图像\源数据['image'][0];
var f=滑块值;
对于(var j=0;j

bokeh版本0.12.15的更新:

import numpy as np
import bokeh
import bokeh.plotting

N = 100

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

source = bokeh.models.ColumnDataSource(
    data=dict(values=[d],x_vals=[x],y_vals=[y]))

p = bokeh.plotting.figure(plot_width=300, plot_height=300,
    x_range=[0, 10], y_range=[0, 10])
p.image(image='values', x=0, y=0, dw=10, dh=10, 
    palette="Spectral11", source=source)

callback = bokeh.models.CustomJS(args=dict(source=source), code="""
    var f = slider.value;
    var x = source.data['x_vals'][0];
    var y = source.data['y_vals'][0];
    var d = source.data['values'][0];
    for (var j = 0; j < y.length; j++){
        for (var i = 0; i < x.length; i++) {
            d[j*y.length + i] = Math.sin(f*x[i]) * Math.cos(f*y[j]);
        }
    }
    source.change.emit();
    """)

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1,
    title="angular frequency",callback=callback)
callback.args['slider'] = slider
layout = bokeh.models.layouts.Row(p,slider)

bokeh.io.output_notebook()
bokeh.io.show(layout)
将numpy导入为np
进口波基
导入bokeh.plotting
N=100
x=np.linspace(0,10,N)
y=np.linspace(0,10,N)
xx,yy=np.meshgrid(x,y)
d=np.sin(xx)*np.cos(yy)
source=bokeh.models.ColumnDataSource(
数据=dict(值=[d],x值=[x],y值=[y]))
图(图宽=300,图高=300,
x_范围=[0,10],y_范围=[0,10])
p、 图像(图像=值),x=0,y=0,dw=10,dh=10,
调色板=“光谱11”,源=源)
callback=bokeh.models.CustomJS(args=dict(source=source),code=”“”
var f=滑块值;
var x=源数据['x_vals'][0];
变量y=源数据['y_vals'][0];
var d=源数据['values'][0];
对于(var j=0;j

你就是那个人。谢谢你,朋友。我真的很感激。看到我犯的错误使我更好地了解了数据源的情况。
import numpy as np
import bokeh
import bokeh.plotting

N = 100

x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)  

source = bokeh.models.ColumnDataSource(
    data=dict(values=[d],x_vals=[x],y_vals=[y]))

p = bokeh.plotting.figure(plot_width=300, plot_height=300,
    x_range=[0, 10], y_range=[0, 10])
p.image(image='values', x=0, y=0, dw=10, dh=10, 
    palette="Spectral11", source=source)

callback = bokeh.models.CustomJS(args=dict(source=source), code="""
    var f = slider.value;
    var x = source.data['x_vals'][0];
    var y = source.data['y_vals'][0];
    var d = source.data['values'][0];
    for (var j = 0; j < y.length; j++){
        for (var i = 0; i < x.length; i++) {
            d[j*y.length + i] = Math.sin(f*x[i]) * Math.cos(f*y[j]);
        }
    }
    source.change.emit();
    """)

slider = bokeh.models.Slider(start=0.1, end=4, value=1, step=.1,
    title="angular frequency",callback=callback)
callback.args['slider'] = slider
layout = bokeh.models.layouts.Row(p,slider)

bokeh.io.output_notebook()
bokeh.io.show(layout)