python - 在 Jupyter 中使用 @interact 装饰器时实现 "reset"按钮

标签 python jupyter ipywidgets

我正在尝试做一个简单的按钮来将小部件“重置”为某些默认值。我正在使用 @interact Jupyter Lab 环境中的装饰器。问题是小部件标识符的值被复制到函数内用作浮点变量的相同标识符,因此我无法在这个新范围内再访问它们。这是一个简短的示例(不起作用):

import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, Button

@interact(starts_at=(0, np.pi*0.9, np.pi*0.1), ends_at=(np.pi, 2*np.pi, np.pi*0.1))
def plot_graph(starts_at=0, ends_at=2*np.pi):
    
    def on_button_clicked(_):
        # instructions when clicking the button (this cannot work)
        starts_at = 0
        ends_at = 2*np.pi
        
    button = Button(description="Reset")
    button.on_click(on_button_clicked)
    display(button)
    
    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])
有人知道如何将对原始小部件对象的引用发送到装饰函数的范围吗?我也将接受实现按钮以重置这些 slider 的简单方法。
:-D
编辑:更正的文本流

最佳答案

要完成此操作,您必须使用更多手册 interactive_output功能。该功能允许您预先创建小部件,然后将它们传入:

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})
但是,这将在您每次更新时完全重新生成情节,这可能会导致不稳定的体验。因此,您也可以重新编写它以使用 matplotlib 方法,如 .set_data如果您在笔记本中使用交互式 matplotlib 后端。因此,如果您要使用 ipympl您可以按照 this example notebook 中的示例进行操作.
通过另一个图书馆
我写了一个库mpl-interactions使用 ipywidgets slider 更容易控制 matplotlib 图。它提供了一个类似于 ipywidgets.interact 的功能。因为它会为您创建小部件,但它具有专注于 matplotlib 的优势,因此您需要提供的只是数据。更多关于 ipywidgets 的区别 here
%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)

关于python - 在 Jupyter 中使用 @interact 装饰器时实现 "reset"按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63958693/

相关文章:

python - pygame 坠落碰撞导致玩家上下振荡

python - 二维多边形的交集

Sage Math 9.0 (Jupyter) 中的 Python Pandas - Windows

python - 如何通过交互包装函数修改matplotlibFig,ax对象?

Python正则表达式搜索,匹配不匹配

jupyter - %stored Jupyter 文件位于何处?

python - 如何在 Jupyter Notebook Python 3.6.2 中关闭行号

ipython - 使用 Ipython ipywidget 创建变量?

python - 如何有条件地评估 bash 脚本

python - *.so 文件如何工作,以及它们在 UNIX 中的位置?