我对Python和Stackoverflow还是比较陌生,如果已经问过这个问题,我深表歉意,但是我已经搜索了很长一段时间,并且无法真正找到要解决的方法。
问题:
我一直在尝试创建一个非常基本的COVID-19流行病模型,以使自己熟悉Python。我的目的是要生成一个基本的SIR模型,该模型可以计算人口中易感,受感染和被清除的个体。到目前为止,一切都很好。
我的问题是,我希望该图具有一个交互式滑块,该滑块可以改变微分方程中的常数之一。
我正在使用Bokeh,并试图为此使用Javascript回调,但是我在使用Javascript时遇到了困难。到目前为止,我所看到的所有示例都使用线方程,其中y是x的函数,并且相对容易编写代码。就我而言,由于它是一个微分方程组,所以我不确定该如何处理。
我也尝试过使用scipy,但仍然遇到相同的问题。
下面的代码。任何帮助/反馈/建议将不胜感激。
谢谢!
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)
这是我想出的。有趣的是,当beta值较高时,易受干扰的行会降至0以下。也许在将您的代码移植到JavaScript时我犯了一个错误-如果可以,请更正。
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])