多个interact()命令在IPython中复制小部件

时间:2016-01-22 14:22:34

标签: python ipython jupyter-notebook ipywidgets

我使用的是IPython Jupyter笔记本。在下列情况下,我使用interact()调用函数,然后使用interact()再次调用第二个函数。

def fun1(dataset_id):
     dataset = read_dataset(dataset_id)
     interact(fun2, data=dataset, var=(0,dataset.property,0.1))

def fun2(data, var):
     # something

interact(fun1, dataset_id=(0,5,1))

首次运行时,它会显示2个滑块小部件:一个用于dataset_id,另一个用于变量var。但是,如果我改变dataset_id滑块一次,var的第二个滑块会添加到第一个var滑块下方,所以现在我总共有3个滑块。我怎么能避免这个?

3 个答案:

答案 0 :(得分:1)

这只是不那么苛刻的一步,但至少你没有按钮:

from ipywidgets import *
from IPython.display import display

datasets=[{"property":1},{"property":2},{"property":3},{"property":4},{"property":5}]

def read_dataset(dataset_id):
    return datasets[dataset_id]

def fun1(dataset_id):
    global sliders
    try:
        sliders.close()
    except NameError:
        pass
    dataset = read_dataset(dataset_id)
    sliders =  interactive(fun2, data=fixed(dataset), var=(0,dataset["property"],0.1)) # note I am now using interactive, instead of interact, because I need the close() function
    display(sliders)

def fun2(data, var):
    print var

interact(fun1, dataset_id=(0,5,1))

答案 1 :(得分:0)

经过一个令人沮丧的一天后,我想出了一个完全黑客的解决方法(但至少它实现了我想要的100%)。我正在添加一个按钮,当单击该按钮时,会在第二个滑块上以及按钮本身上调用.close()。因此,之前每次我需要移动第一个滑块时,按此按钮清除。

以下是基于问题代码段的功能完备的代码,您可以在解释器中进行复制粘贴。

from ipywidgets import *
from IPython.display import display

datasets=[{"property":1},{"property":2},{"property":3},{"property":4},{"property":5}]

def read_dataset(dataset_id):
    return datasets[dataset_id]

def fun1(dataset_id):
    dataset = read_dataset(dataset_id)
    sliders = interactive(fun2, data=fixed(dataset), var=(0,dataset["property"],0.1)) # note I am now using interactive, instead of interact, because I need the close() function
    close_button = widgets.Button(description="Remove sliders")
    def remove_sliders(b):
        sliders.close()
        b.close()
    close_button.on_click(remove_sliders)
    display(sliders)
    display(close_button)

def fun2(data, var):
    print
    # something

interact(fun1, dataset_id=(0,5,1))

答案 2 :(得分:0)

这是另一个解决方案,您可以创建两个滑块,并使第二个滑块的“max”取决于使用第一个滑块选择的属性:

import ipywidgets as widgets
from ipywidgets import *
from IPython.display import display

datasets=[{"property":1},{"property":2},{"property":3},{"property":4},{"property":5}]

def read_dataset(dataset_id):
    return datasets[dataset_id]

w_slider1 = IntSlider(min=0, max=len(datasets)-1, step=1)
w_slider2 = FloatSlider(min=0, step=0.1)

def fun1(dataset_id):
    dataset = read_dataset(dataset_id)
    #you could get rid of function "read_dataset"
    #dataset = datasets[dataset_id]
    w_slider2.max = dataset['property']

def fun2(data, var):
    #call fun1 to update the size of 2nd slider
    fun1(data)
    #do something
    print(data, var)

interact(fun2, data=w_slider1, var=w_slider2)