我正在尝试使用散景及时绘制我的1D PDE。我有一个nparray U,其中每一行是一个时间片(dt),每列是一个空间片(dx),因此U [0]是我的初始条件,U [n]是我的第n次迭代。
当然,如果我要求为每个t绘制(x,U [t]),我得到正确的情节(和我的近似值一样好;-),但我想将它与时间滑块相关联互动(当然在未来我想把它作为动画“播放”; - )
现在我想避免使用散景服务器,因为我希望这个HTML是一个独立的“应用程序”
这里的问题是回调不起作用,或者至少我无法更新图表。我不想运行“散景”服务器,因为我的所有数据都已经在一个numpy数据结构(U数组)中。每一行都是时间迭代,每列都是dx。
#!/usr/bin/env python
from __future__ import division
from bokeh.models import ColumnDataSource, HBox, VBoxForm, HoverTool
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import Figure, output_file, show
import numpy as np
def linearconv(nx,c=1,sigma=0.5,tmax=1,xmax=3):
nt=int((tmax/xmax)*((nx-1)/(c*sigma))+1) # Time Grid
x,dx=np.linspace(0,xmax,nx,retstep=True)
t,dt=np.linspace(0,tmax,nt,retstep=True)
# Initial conditions
#
# u=2 if 0.5 <= x <= 1
# u=1 everywhere else in the support
U = np.ones((nt,nx))
U[0][np.where((.5<=x) & (x<=1))]=2
# Calculate the wave over the time
for n in range(1,nt):
for i in range(1,nx):
U[n][i]= U[n-1][i] - c*dt/dx* ( U[n-1][i]-U[n-1][i-1] )
return U,x,t,dx,dt,nt
def prepareplot(height=400, width=400,title="Wave @"):
plot = Figure(plot_height=height, plot_width=width, title=title,
tools="crosshair,pan,reset,resize,save,wheel_zoom")
return plot
def update_ttime(attrname, old, new):
plot.title = "Wave @{}s".format(title.value)
def update_graph(attrname, old, new):
# Get the current slider values
t = time.value
source = ColumnDataSource(data=dict(x=x, t=U[t]))
plot.line('x','t', source=source)
plot.line('x','t', source=source)
nx=101
# Set up data
U,x,t,dx,dt,nt = linearconv(nx)
plot = prepareplot()
time = Slider(title="Time", value=t[-1], start=t[0], end=t[-1], step=dt)
ttime = TextInput(title="Time", value="{}".format(t[-1]))
source = ColumnDataSource(data=dict(x=x, t=U[-1]))
plot.line('x','t', source=source)
# Set up callbacks
ttime.on_change('value', update_ttime)
time.on_change('value', update_graph)
# Setup layouts
inputs = VBoxForm(children=[ttime,time])
layout = HBox(children=[inputs,plot], width=800)
# Plot the plot
output_file("sli.html")
show(layout)