前言
上一篇介绍 interact 基本的用法,可以设计使用者介面(UI),但无法取得输入值,本篇介绍使用另一函数 interactive,可克服此一问题。
测试
废话不多说,直接以程式说明。
from ipywidgets import interactivefrom IPython.display import displaydef f(a, b): display(a + b) return a+b # interactive 预设不会显示 UIw = interactive(f, a=10, b=20)# 显示 UIdisplay(w)
乍看之下,有点难懂,interactive 设定UI,display 显示UI,并显示计算结果。
以下程式码可取得输入值。
w.kwargs
执行结果:{'a': 21, 'b': -10}
以下程式码可取得函数传回值。
w.result
执行结果:11
还有一个好处,display(w) 可重複呼叫,显示 UI。
手动更新
使用拉桿调整输入值时,interact、interactive 都会即时更新计算结果,但有的函数计算很複杂或须查询资料库,很费时,就会希望输入值确定后,才计算结果,这时可以使用下列三种方法。
改用 interact_manual。# 计算很複杂的函数def slow_function(i): print(int(i),list(x for x in range(int(i)) if str(x)==str(x)[::-1] and str(x**2)==str(x**2)[::-1])) return # 手动更新from ipywidgets import interact_manual, FloatSliderinteract_manual(slow_function,i=FloatSlider(min=1e5, max=1e7, step=1e5));
执行结果:会出现一个『Run Interact』按钮,按下后才会执行函数。
interact(slow_function,i=FloatSlider(min=1e5, max=1e7, step=1e5, continuous_update=False));
也可以使用interactive。slow = interactive(slow_function, {'manual': True}, i=widgets.FloatSlider(min=1e4, max=1e6, step=1e4))slow
画面设计(UI Layout)
多个输入可以安排摆放位置。以下三个输入水平排列。
import ipywidgets as widgets# 使用 Slidera = widgets.IntSlider()b = widgets.Text()c = widgets.IntSlider()# HBox:水平排列ui = widgets.HBox([a, b, c])def f(ID, Name, Age): print((ID, Name, Age))out = widgets.interactive_output(f, {'ID': a, 'Name': b, 'Age': c})display(ui, out)
执行结果:
out 可以取得执行结果 (37, 'Mary', 20)。
互相关联的输入栏位
一个输入栏位可能会因另一输入栏位有所变化,例如联谊男性限40岁、女性限30岁,类似情况程式码如下。
x_widget = FloatSlider(min=0.0, max=10.0, step=0.05)y_widget = FloatSlider(min=0.5, max=10.0, step=0.05, value=5.0)def update_x_range(*args): # x 输入栏最大值随 y_widget 而变化 x_widget.max = 2.0 * y_widget.value # x_widget 随 y_widget 而变化y_widget.observe(update_x_range, 'value')def printer(x, y): print(x, y) interact(printer,x=x_widget, y=y_widget);
执行结果:先将x设为最大值,再移动y,会发现 x 随 y 变化。
应用
以下以简单线性迴归绘图为例,设定斜率(m)及截距(b),画出迴归线。
from ipywidgets import interactiveimport matplotlib.pyplot as pltimport numpy as npdef f(m, b): plt.figure(2) x = np.linspace(-10, 10, num=1000) plt.plot(x, m * x + b) plt.ylim(-5, 5) plt.show()interactive_plot = interactive(f, m=(-2.0, 2.0), b=(-3, 3, 0.5))output = interactive_plot.children[-1]output.layout.height = '350px'interactive_plot
执行结果:
结论
设计 Notebook 时,只要加一点简单的UI,使用者的爽度就会加倍,对于程式的理解与测试也更加容易,因此,多花点时间撰写也值得了。