3 回答

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個(gè)贊
要完成此操作,您必須使用更多手動(dòng)interactive_output功能。該函數(shù)允許您預(yù)先創(chuàng)建小部件,然后將它們傳入:
import ipywidgets as widgets
import numpy as np
import matplotlib.pyplot as plt
start_slider = widgets.FloatSlider(
? ? ? ? ? ? ? ? ? ? ? ? ? ? val = 0,
? ? ? ? ? ? ? ? ? ? ? ? ? ? min = 0,
? ? ? ? ? ? ? ? ? ? ? ? ? ? max = np.pi*0.9,
? ? ? ? ? ? ? ? ? ? ? ? ? ? step = np.pi*0.1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? description = 'Starts at'
? ? ? ? ? ? ? ? ? ? ? ? ? ? )
end_slider = widgets.FloatSlider(
? ? ? ? ? ? ? ? ? ? ? ? ? ? val = np.pi,
? ? ? ? ? ? ? ? ? ? ? ? ? ? min = np.pi,
? ? ? ? ? ? ? ? ? ? ? ? ? ? max = 2*np.pi,
? ? ? ? ? ? ? ? ? ? ? ? ? ? step = np.pi*0.1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? description = 'Ends at'
? ? ? ? ? ? ? ? ? ? ? ? ? ? )
def on_button_clicked(_):
? ? start_slider.value = 0
? ? end_slider.value = 2*np.pi
button = Button(description="Reset")
button.on_click(on_button_clicked)
def plot_graph(starts_at=0, ends_at=2*np.pi):
? ? f = lambda x : sum(1/a*np.sin(a*x + np.pi/a) for a in range(1,6))
? ? x = np.linspace(0, 2*np.pi, 1000)
? ? plt.plot(x, f(x))
? ? plt.xlim([starts_at, ends_at])
display(widgets.VBox([start_slider, end_slider, button]))
widgets.interactive_output(plot_graph, {'starts_at': start_slider, 'ends_at':end_slider})
然而,這將在您每次更新時(shí)完全重新生成情節(jié),這可能會(huì)導(dǎo)致不穩(wěn)定的體驗(yàn)。因此,您還可以重寫(xiě)它以使用 matplotlib 方法,就像.set_data
在筆記本中使用交互式 matplotlib 后端一樣。因此,如果您要使用ipympl,您可以按照此示例筆記本中的示例進(jìn)行操作。
通過(guò)另一個(gè)圖書(shū)館
我編寫(xiě)了一個(gè)mpl-interactions庫(kù),以便更輕松地使用 ipywidgets 滑塊控制 matplotlib 繪圖。ipywidgets.interact
它提供了一個(gè)類似于為您創(chuàng)建小部件的功能,但它的優(yōu)點(diǎn)是專注于 matplotlib,因此您需要提供的只是數(shù)據(jù)。%matplotlib ipympl
import mpl_interactions.ipyplot as iplt
import matplotlib.pyplot as plt
import numpy as np
import ipywidgets as widgets
def plot_graph(starts_at=0, ends_at=2*np.pi):
? ? x = np.linspace(starts_at, ends_at, 1000)
? ? f = lambda x : sum(1/a*np.sin(a*x + np.pi/a) for a in range(1,6))
? ? return np.array([x, f(x)]).T
fig, ax = plt.subplots()
button = widgets.Button(description = 'reset')
display(button)
controls = iplt.plot(plot_graph, starts_at = (0, np.pi), ends_at = (np.pi, 2*np.pi), xlim='auto', parametric=True)
def on_click(event):
? ? for hbox in controls.controls.values():
? ? ? ? slider = hbox.children[0]
? ? ? ? slider.value = slider.min
button.on_click(on_click)

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
我可以在不使用裝飾器的情況下弄清楚它@interact(現(xiàn)在它正在工作),但我對(duì)最終結(jié)果不滿意。所以,我仍然愿意為那些可以做出清晰/更簡(jiǎn)單的Python版本的人提供正確的答案狀態(tài)。
無(wú)論如何,這是工作代碼:
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, Button, FloatSlider
def plot_graph(starts_at, ends_at):
f = lambda x : sum(1/a*np.sin(a*x + np.pi/a) for a in range(1,6))
x = np.linspace(0, 2*np.pi, 1000)
plt.plot(x, f(x))
plt.xlim([starts_at, ends_at])
starts_at = FloatSlider(min=0, max=np.pi*0.9, value=0, step=np.pi*0.1)
ends_at = FloatSlider(min=np.pi, max=2*np.pi, value=2*np.pi, step=np.pi*0.1)
def on_button_clicked(_):
starts_at.value = 0
ends_at.value = 2*np.pi
button = Button(description="Reset")
button.on_click(on_button_clicked)
display(button)
_ = interact(plot_graph, starts_at=starts_at, ends_at=ends_at)
編輯:從這一點(diǎn)開(kāi)始的新方法================================
我選擇 @Ianhi 答案作為正確的答案,因?yàn)樗赋隽嗽谖业膯?wèn)題背景下要考慮的問(wèn)題。謝謝!
不管怎樣,我在這里發(fā)布了我正在使用的最終方案,該方案對(duì)于我的需求來(lái)說(shuō)足夠簡(jiǎn)單,并且我可以在所有交互中重復(fù)使用重置按鈕:
# Preamble ----
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, Button, FloatSlider
def reset_button(defaults={}):
def on_button_clicked(_):
for k, v in defaults.items():
k.value = v
button = Button(description='Reset')
button.on_click(on_button_clicked)
display(button)
# Code ----
slider1 = FloatSlider(min=0, max=np.pi*0.9, value=0, step=np.pi*0.1)
slider2 = FloatSlider(min=np.pi, max=2*np.pi, value=2*np.pi, step=np.pi*0.1)
reset_button(defaults={slider1: 0, slider2: 2*np.pi})
@interact(starts_at=slider1, ends_at=slider2)
def plot_graph(starts_at, ends_at):
f = lambda x : sum(1/a*np.sin(a*x + np.pi/a) for a in range(1,6))
x = np.linspace(0, 2*np.pi, 1000)
plt.plot(x, f(x))
plt.xlim([starts_at, ends_at])

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超9個(gè)贊
您可以創(chuàng)建一個(gè)簡(jiǎn)單的裝飾器,為每次使用添加一個(gè)重置按鈕:
按照上面的答案重置按鈕:
def reset_button(defaults={}):
? ? def on_button_clicked(_):
? ? ? ? for k, v in defaults.items():?
? ? ? ? ? ? k.value = v
? ? button = widgets.Button(description='Reset')
? ? button.on_click(on_button_clicked)
? ? display(button)
裝飾者:
def interact_plus_reset(**_widgets):
? default_vals = {wid:wid._trait_values['value'] for k, wid in _widgets.items()}
? reset_button(defaults=default_vals)
? def wrap(func):
? ? @wraps(func)
? ? @widgets.interact(**_widgets)
? ? def inner(*args, **kwargs):
? ? ? return func(*args, **kwargs)
? ? return inner
? return wrap
然后按如下方式使用它:
@interact_plus_reset(
? a = widgets.FloatSlider(min=1, max=2000, value=35, step=1),?
? b = widgets.FloatSlider(min=1, max=2000, value=1000, step=1),?
)
def run(a, b):
? print(a + b)
添加回答
舉報(bào)