如何与包含小部件的 Box 交互使用?

How to use interactive with a Box containing widgets?

使用 interactive 与多个小部件相当简单,例如:

interactive(foo, w1=widget1, w2=widget2, ...)

但是我想以特定方式布置这些小部件,使用 VBox 和 HBox 的组合。问题是,我如何使用盒子进行交互?

我尝试了几种方法,例如调用与 Box 的小部件交互然后显示框本身,但这似乎不起作用。

它在小部件中 documentation:

In addition to interact, IPython provides another function, interactive, that is useful when you want to reuse the widgets that are produced or access the data that is bound to the UI controls. [...] Unlike interact, interactive returns a Widget instance rather than immediately displaying the widget. The widget is a Box, which is a container for other widgets.

所以这里您已经有了 w 作为您可以更改其布局属性的 Box 容器。

w = interactive(foo, w1=widget1, w2=widget2)

我遇到了同样的问题,发现我们需要使用 interactive_output

out = interactive_output(foo, {"w1":w1, "w2":w2, "w3":w3, "w4":w4})
vbox1 = VBox([w1, w2])
vbox2 = VBoX([w3, w4])
ui = HBox([vbox1, vbox2])

accordian = Accordian(children=[ui])
accordian.set_title(0, 'Title')

display(accordian, out)

使用interactive_output

类似于:

t1 = Text(value='Hello 1', description='row 1')
t2 = Text(value='Hello 2', description='')
t3 = Text(value='Hello 3', description='')
t4 = Text(value='Hello 4', description='row 2')
t5 = Text(value='Hello 5', description='')
t6 = Text(value='Hello 6', description='')
t7 = Text(value='Hello 7', description='row 3')
t8 = Text(value='Hello 8', description='')
t9 = Text(value='Hello 9', description='')

def foo(p1,p2,p3,p4,p5,p6,p7,p8,p9):
    print(p1,p2,p3,p4,p5,p6,p7,p8,p9)

out = interactive_output(foo, {"p1":t1, "p2":t2, "p3":t3, "p4":t4, "p5":t5, "p6":t6, "p7":t7, "p8":t8, "p9":t9})
hbox1 = HBox([t1, t2, t3])
hbox2 = HBox([t4, t5, t6])
hbox3 = HBox([t7, t8, t9])
ui = VBox([hbox1, hbox2, hbox3])

display(ui, out)

(注意:这是我第一次在堆栈溢出中回答,如果我还没有弄清楚如何在这里 post 代码块,我深表歉意,但我会尽力格式化它们。 )

就像别人说的那样,用interactive_output。从 https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html 的文档中, 有一个示例代码说明了这一点:

a = widgets.IntSlider()
b = widgets.IntSlider()
c = widgets.IntSlider()
ui = widgets.HBox([a, b, c])
def f(a, b, c):
    print((a, b, c))

out = widgets.interactive_output(f, {'a': a, 'b': b, 'c': c})

display(ui, out)

我实际上在我自己的代码中实现了这个,我使用 HBox 和 VBox 来形成一个 2x2 的小部件网格。我正在绘制指数函数和一般正弦波的乘积,其振幅、指数衰减、频率和相位通过滑块变化。这是代码:

import numpy as np
import matplotlib.pyplot as plt
import ipywidgets as wgs
from ipywidgets import HBox, VBox
%matplotlib inline

def f(A, decay, wd, phase):
    t = np.linspace(0, 2*np.pi, 501)
    fig, ax = plt.subplots(figsize=(14,4), dpi=100)
    x = A*np.exp(-decay*t)*np.sin(wd*t + phase)
    ax.plot(t, x, 'b.', linewidth = 3)
    ax.grid()
    ax.set_title(r'$ %(amp)s e^{ -%(sig)s t} sin( %(wd)s t + %(phi)s ) $' %{'amp':A, 'sig':decay, 'wd':wd, 'phi':phase,} )
    ax.set_xlabel('t')
    ax.set_ylabel('x(t)')
    ax.set_xlabel('Time (seconds)')
    ax.set_ylabel('Displacement (meters)')
    ax.set_xticks(np.linspace(min(t),max(t), 21))
    ax.set_yticks(np.linspace(-A, A,11))  
    return A, decay, wd, phase
A  = wgs.IntSlider(value = 1, min = 1, max = 10, step = 1, description = r'$ A : $', disabled=False)
decay = wgs.FloatSlider(value = 0, min = 0, max = 10, step = 0.5, description = r'$ \sigma : $', disabled=False)
wd    = wgs.IntSlider(value = 1, min = 1, max = 20, step = 1, description = r'$ \omega_d : $', disabled=False)
phase = wgs.FloatSlider(value = 0, min = -1.5, max = 1.5, step = 0.1, description = r'$ \phi : $', disabled=False)
row1 = HBox( [A, decay] )
row2 = HBox( [wd, phase] )
ui = VBox( [row1, row2] )
out = wgs.interactive_output(f, {'A':A, 'decay':decay, 'wd':wd, 'phase':phase} )
display(ui, out)