我正在制作独立的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个空格,还是有更快的方式?