Bokeh CustomJS加载javascript类

时间:2017-11-20 18:15:31

标签: javascript python-3.x bokeh

我正在制作独立的HTML对象,并且我想知道在使用CustomJS时如何使用比Math.sin()等更多的命令。理想情况下,我想使用flexx以python语言编写回调函数,并将使用numpy创建的数组传递给回调函数。我直接关注的是包含复数,而我更一般的方向将涉及fft代码。

在使用Python 3的jupyter笔记本中,我可以执行以下操作:

#created by Kyle Johnston
import numpy as np

from ipywidgets import interact

from bokeh.models.widgets import Panel, Tabs
from bokeh.plotting import figure, output_file, show, save
from bokeh.models.layouts import Row, Column, WidgetBox
from bokeh.io import output_notebook, show, push_notebook, save, file_html, output_file
from bokeh.layouts import gridplot,layout
from bokeh.models import ColumnDataSource, HoverTool, CustomJS, Range1d, Slider
from bokeh.palettes import Spectral4

################## Defintions #########################################

c= 3e8
IR = 2000e-9
VIS = 2000e-9
t = np.linspace(-200.*1e-15,200.*1e-15,2000)

E_IR=1; w_IR= c*2*np.pi/IR; tau_IR= 70.*1e-15
E_VIS=1; w_VIS= c*2*np.pi/VIS; tau_VIS= 6*1e-15
E_field_IR = E_IR*np.exp(1j*t*w_IR)*np.exp(-2*np.log(2)*(t/tau_IR)**2)
E_field_VIS = E_VIS*np.exp(1j*t*w_VIS)*np.exp(-2*np.log(2)*(t/tau_VIS)**2)
E_f_IR_Real = np.real(E_field_IR)
E_f_VIS_Real = np.real(E_field_VIS)

tau_1= tau_IR; w_1=w_IR;
tau_2= tau_VIS; w_2=w_VIS;
x1 = t
x2 = t
y1 = np.sin(2*np.pi*c*x1/IR)*np.exp(-(x1/tau_1)**2)
y2 = np.sin(2*np.pi*c*x2/IR)*np.exp(-(x1/tau_2)**2)
y3 = y1+y2
# y1 = np.sin(w_1*x1)
# y2 = np.sin(w_2*x2)
source1 = ColumnDataSource(data=dict(x1=x1, y1=y1))
source2 = ColumnDataSource(data=dict(x2=x2, y2=y2))
source3 = ColumnDataSource(data=dict(x2=x2, y3=y3))

################ Figures ##############################################
p = figure(y_range=(-5, 5), plot_width=700, plot_height=600)

p.line('x1', 'y1', source=source1, line_width=3, line_alpha=1,\
   color='green',legend='wave1')
p.line('x2', 'y2', source=source2, line_width=3, line_alpha=1,\
   color='blue',legend='wave2')
p.line('x2', 'y3', source=source3, line_width=2, line_alpha=0.5,\
   color='purple',legend='sum')


################# Callback to update figures    ##########################################

callback = CustomJS(args=dict(source1=source1,source2=source2,source3=source3), code="""
    var data1 = source1.data;
    var data2 = source2.data;
    var data3 = source3.data;
    var delay = 1e-15*delay.value;
    var A1 = amp1.value;
    var k1 = wave1.value;
    var phi1 = phase1.value;
    var B1 = offset1.value;
    var tau1 = 1e-15*tau1.value;
    var A2 = amp2.value;
    var k2 = wave2.value;
    var phi2 = phase2.value;
    var B2 = offset2.value;
    var tau2 = 1e-15*tau2.value;

    x1 = data1['x1']
    y1 = data1['y1']
    x2 = data2['x2']
    y2 = data2['y2']
    y3 = data3['y3']

    for (i = 0; i < x1.length; i++) {
        y1[i] = B1+A1*Math.sin(phi1+3e8*2*Math.PI*(delay+x1[i])/(k1*1e-9))*Math.exp(-Math.pow((delay+x1[i])/tau1,2));
        y2[i] = B2+A2*Math.sin(phi2+3e8*2*Math.PI*x2[i]/(k2*1e-9))*Math.exp(-Math.pow(x2[i]/tau2,2));
        y3[i] = y1[i]+y2[i];
    }
    source1.change.emit();
""")



delay_slider_1 = Slider(start=-400, end=400, value=0, step=1,
                title="Delay (fs)", callback=callback)
callback.args["delay"] = delay_slider_1

amp_slider_1 = Slider(start=0.1, end=1, value=1, step=.1,
                title="Amplitude 1", callback=callback)callback.args["amp1"] = amp_slider_1

wave_slider_1 = Slider(start=700, end=3000, value=2000, step=10,
                 title="Wavelength  1 (nm)", callback=callback)
callback.args["wave1"] = wave_slider_1

phase_slider_1 = Slider(start=-10*np.pi, end=10*np.pi, value=0,    
                    step=np.pi/10, title="Phase 1", callback=callback)
callback.args["phase1"] = phase_slider_1

offset_slider_1= Slider(start=-5, end=5, value=0, step=.1,
                   title="Offset 1", callback=callback)
callback.args["offset1"] = offset_slider_1

tau_slider_1 = Slider(start=1, end=100, value=70, step=1,
                   title="tau 1 (fs)", callback=callback)
callback.args["tau1"] = tau_slider_1

######################### Wave 2 ###################################
amp_slider_2 = Slider(start=0.1, end=1, value=1, step=.1,
                title="Amplitude 2", callback=callback)
callback.args["amp2"] = amp_slider_2

wave_slider_2 = Slider(start=700, end=3000, value=2000, step=10,
                 title="Wavelength 2 (nm)", callback=callback)
callback.args["wave2"] = wave_slider_2

phase_slider_2 = Slider(start=-10*np.pi, end=10*np.pi, value=0,
                    step=np.pi/10,title="Phase 2", callback=callback)
callback.args["phase2"] = phase_slider_2

offset_slider_2 = Slider(start=-5, end=5, value=0, step=.1,
                   title="Offset 2", callback=callback)
callback.args["offset2"] = offset_slider_2

tau_slider_2 = Slider(start=1, end=100, value=5, step=1,
                   title="tau 2 (fs)", callback=callback)
callback.args["tau2"] = tau_slider_2


###################### Make Layout and activate clickable plot   #######################################
p.legend.location = "top_left"
p.legend.click_policy="hide"
p.y_range=Range1d(-2.1,2.1)
p.x_range
p.xaxis.axis_label = 'time(s)'
p.yaxis.axis_label = 'Amplitude (arb)'


l = layout(Column(
p,WidgetBox(delay_slider_1),
Row(Column(WidgetBox(amp_slider_1, wave_slider_1, phase_slider_1, \
                     offset_slider_1, tau_slider_1)),
Column(WidgetBox(amp_slider_2, wave_slider_2, phase_slider_2,\
                 offset_slider_2, tau_slider_2)))
))

show(l)

这会产生一个精彩的互动情节。

你可以看到我在回调中重写了数学,因为我不知道如何在回调中包含复数。我想知道如何将apache commons math包链接到我的笔记本中,和/或如何在回调中使用numpy创建它。据我所知,flexx在回调内部启用python脚本,除了实际的数学部分之外的一切。 有点像jpype我需要使用的东西吗?

我希望上面的例子可以帮助某人,而且有人可以帮助我。

P.S。此外,由于这是我的第一个问题,我希望工作示例完整。我是否真的必须一行一行地添加4个空格,还是有更快的方式?

0 个答案:

没有答案