首页 > 解决方案 > python bokeh 以交互方式在 min 和 max 之间绘制 n 条曲线

问题描述

我正在尝试生成两个参数的函数图,其中一个用作 x_axis,另一个我绘制 n 曲线,在最小值和最大值之间改变参数。

以下代码有效:

import numpy as np
import bokeh
from bokeh.plotting import figure
from bokeh.io import push_notebook, show, output_notebook
output_notebook()
x = np.linspace(0,10,100)
f = figure()

fmin=1
fmax=3
nfreq=4

freq=np.linspace(fmin,fmax,nfreq)

for i in freq:
    y = np.sin(i*x)
    f.line(x,y)
show(f)  

现在我想要 3 个滑块以交互方式改变 fmin、fmax 和 nfreq。我无法弄清楚该怎么做......

谢谢你的帮助

标签: python-3.xbokeh

解决方案


此示例适用于 Bokeh v1.0.4。运行方式:bokeh serve --show app.py app.py 的内容:

import numpy as np
from bokeh.models import Slider, Row, Column
from bokeh.plotting import figure, show, curdoc
from bokeh.models.sources import ColumnDataSource

plot = figure()
layout = Column(plot)
sources, lines = {}, {}

def get_x(n): return [np.linspace(0, 10, 100) for i in range(n)]
def get_y(n): return [np.sin(i * np.linspace(0, 10, 100)) for i in n]

def update(attr, old, new): 
    update_sources(layout.children[-3].value, layout.children[-2].value, layout.children[-1].value)

def update_sources(fmin, fmax, nfreq):
    freq = np.linspace(fmin, fmax, nfreq)
    for f, x, y in zip(freq, get_x(len(freq)), get_y(freq)):
        data = {'x': x, 'y': y}
        if f not in sources:
            sources[f] = ColumnDataSource(data)
            line = plot.line('x', 'y', source = sources[f])
            lines[f] = line
        else:
            sources[f].data = data
    for line in lines:
        lines[line].visible = (False if line not in freq else True)

for txt, max in zip(['fmin', 'fmax', 'nfreq'], [3, 4, 5]):
    slider = Slider(start = 1, end = max, value = 1, title = txt)
    slider.on_change('value', update)
    layout.children.append(slider)

update_sources(layout.children[-3].value, layout.children[-2].value, layout.children[-1].value)
[plot.line('x', 'y', source = sources[idx]) for idx in sources]
curdoc().add_root(layout)

推荐阅读