javascript - Bokeh JS callback when plotting differential equations
问题描述
I'm relatively new to Python and Stackoverflow so apologies if this question has already been asked but I've searched for quite a while now and can't really find a solution to what I'm trying to do.
Problem:
I've been trying to create a very basic model of the COVID-19 epidemic to familiarise myself with Python. My intention is to produce a basic SIR model that calculates susceptible, infected and removed individuals in a population. So far so good.
My problem is that I would like the plot to have an interactive slider that alters one of the constants in the differential equation.
I am using Bokeh and am trying to use Javascript Callbacks for this however I am having difficulty with the Javascript. All examples I have seen so far use line equations where y is a function of x, and which are relatively straightforward to code. In my case, since its a system of differential equations I'm not sure how I should be going about this.
I've also tried using scipy but I still encounter the same problem.
Code below. Any help/feedback/suggestions would be greatly appreciated.
Thanks!
from bokeh.layouts import column, row
from bokeh.models import CustomJS, Slider
from bokeh.plotting import ColumnDataSource, figure, output_file, show
t = []
for i in range(200):
t.append(i)
slst = []
ilst = []
rlst = []
s = 489599/489609
i = 10/489609
r = 0/489609
bet = 0.28
gam = 0.189
for f in range(200):
ds = (-bet * (s * i))
di = ((bet * (s * i)) - (gam * i))
dr = gam * i
s = s + (ds)
slst.append(s)
i = i + (di)
ilst.append(i)
r = r + (dr)
rlst.append(r)
source = ColumnDataSource(data=dict(x=t, y=[], s=slst, i=ilst))
plot = figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
callback = CustomJS(args=dict(source=source), code="""
????????????
""")
slider = Slider(start=0.1, end=4, value=1, step=.1, title="Beta ")
slider.js_on_change('value', callback)
layout = column(slider, plot)
show(layout)
解决方案
Here's what I've come up with. It's interesting to see that with high values of beta, the susceptible line goes below 0. Maybe I've made a mistake while porting your code to JavaScript - please correct me if so.
from bokeh.core.property.instance import Instance
from bokeh.io import save
from bokeh.layouts import column
from bokeh.model import Model
from bokeh.models import CustomJS, Slider, Callback
from bokeh.plotting import ColumnDataSource, figure
source = ColumnDataSource(data=dict(t=[], s=[], i=[], r=[]))
plot = figure(plot_width=400, plot_height=400)
plot.line('t', 's', source=source, line_width=3, line_alpha=0.6)
plot.line('t', 'i', source=source, line_width=3, line_alpha=0.6, color='orange')
plot.line('t', 'r', source=source, line_width=3, line_alpha=0.6, color='green')
callback = CustomJS(args=dict(source=source), code="""\
const N = 200;
let s = 489599 / 489609;
let i = 10 / 489609;
let r = 0 / 489609;
const bet = cb_obj.value;
const gam = 0.189;
const tlst = source.data.t = [];
const slst = source.data.s = [];
const ilst = source.data.i = [];
const rlst = source.data.r = [];
for (let t = 0; t < N; ++t) {
s -= bet * s * i;
i += bet * s * i - gam * i;
r += gam * i;
tlst.push(t);
slst.push(s);
ilst.push(i);
rlst.push(r);
}
source.change.emit();
""")
slider = Slider(start=0.1, end=4, value=1, step=.1, title="Beta ")
slider.js_on_change('value', callback)
class IdleDocObserver(Model):
"""Work around https://github.com/bokeh/bokeh/issues/4272."""
on_idle = Instance(Callback)
# language=TypeScript
__implementation__ = """\
import {View} from "core/view"
import {Model} from "model"
import * as p from "core/properties"
export class IdleDocObserverView extends View {}
export namespace IdleDocObserver {
export type Attrs = p.AttrsOf<Props>
export type Props = Model.Props & {on_idle: p.Property<any>}
}
export interface IdleDocObserver extends IdleDocObserver.Attrs {}
export class IdleDocObserver extends Model {
static init_IdleDocObserver(): void {
this.prototype.default_view = IdleDocObserverView
this.define<IdleDocObserver.Props>({on_idle: [p.Any]})
}
_doc_attached(): void {
super._doc_attached()
const execute = () => this.on_idle!.execute(this)
if (this.document!.is_idle)
execute();
else
this.document!.idle.connect(execute);
}
}
"""
idle_doc_observer = IdleDocObserver(on_idle=CustomJS(args=dict(callback=callback, slider=slider),
code="callback.execute(slider);"))
layout = column(slider, plot)
save([idle_doc_observer, layout])
推荐阅读
- php - 收到 mail() 多个或格式错误的换行错误
- vba - 从实时网站中提取数据
- cordova - 通过 Cordova 访问需要列入白名单的引用域名的远程 API
- c - 在 c 复合语句中使用宏时
- matrix - 如何在 Mathematica 中求解非对易变量的矩阵方程
- reactjs - hoc的函数无法获取react-redux connect props
- circuit - 如何使用通用移位寄存器实现序列生成器?
- node.js - throw new TypeError('OAuth2Strategy 需要一个 clientID 选项'); }
- arrays - 对包含 8 个元素的数组进行排序的最快方法是什么?
- python - 在 Django 中替换生成密钥的随机部分