【问题标题】:Multiple interact() commands duplicate widgets in IPython多个交互()命令在 IPython 中重复小部件
【发布时间】:2016-01-22 14:22:33
【问题描述】:

我正在使用 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 个滑块。我怎样才能避免这种情况?

【问题讨论】:

    标签: python ipython jupyter-notebook ipywidgets


    【解决方案1】:

    这只是少了一步hacky,但至少你不必有一个按钮:

    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))
    

    【讨论】:

      【解决方案2】:

      在经历了令人沮丧的一天之后,我想出了一个非常老套的方法来解决这个问题(但至少它达到了我想要的 100%)。我正在添加一个按钮,单击该按钮会在第二个滑块以及按钮本身上调用.close()。因此,之前每次我需要移动第一个滑块时,我都会按下这个按钮来清除。

      这是一个基于问题中的 sn-p 的功能齐全的代码,您可以将其复制粘贴到您的解释器中。

      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))
      

      【讨论】:

        【解决方案3】:

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

        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)
        

        【讨论】:

          猜你喜欢
          • 2014-09-17
          • 2015-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多