Djpengo
Djpengo

Reputation: 388

Ipywidgets: alter slider defaults based on a scenario

I'm using ipywidges to create a plot. I'd like to have a dropdown with options (e.g. Scenario A, Scenario B). Each scenario should change the slider position (a=0, b=1), and one should be able to modify the parameters freely afterwards. Any ideas?

Here is my toy example:

import ipywidgets as widgets

def line(a=0,b=1):
    #fig, ax = plt.subplots(figsize=(6, 4))
    x = np.arange(-10,10)
    y = a+xrange*b
    plt.xlim((-10,10))
    plt.ylim((-10,10))
    plt.plot(x, y)
    
widgets.interact(line, a=(-10,10,0.1), b=(-10,10,0.1))

enter image description here

I was playing with an additional wrapper functions but with no success. In reality of course, I would like to have a few more scenarios and a lot more parameters.

Upvotes: 0

Views: 710

Answers (2)

kommandoking
kommandoking

Reputation: 21

Just as another answer, you could also link different widgets. In this case we are going to link the a and b sliders with a Dropdown menu, such that a change of the latter will call the functions on_change_* and switch the default values of the sliders (depending on the chosen scenario).

import ipywidgets as widgets
import numpy as np
import matplotlib.pyplot as plt

def line(a=0,b=0):
    x = np.arange(-10,10)
    y = a+x*b
    plt.xlim((-10,10))
    plt.ylim((-10,10))
    plt.plot(x, y)

    
a_slider = widgets.FloatSlider(min=-10, max=10, step=0.1, value=0)
b_slider = widgets.FloatSlider(min=-10, max=10, step=0.1, value=1)
drop = widgets.Dropdown(options=["a", "b"], value="a", description='Scenario:')


def on_choose_a(d):
    if drop.value == "a":
        a_slider.value = 2
    else:
        a_slider.value = 5
    return a_slider.value


def on_choose_b(d):
    if drop.value == "a":
        b_slider.value = 3
    else:
        b_slider.value = 7
    return b_slider.value

widgets.dlink((drop, "value"), (a_slider, "value"), on_choose_a)
widgets.dlink((drop, "value"), (b_slider, "value"), on_choose_b)

display(drop)
widgets.interact(line, a=a_slider, b=b_slider);

Upvotes: 2

Djpengo
Djpengo

Reputation: 388

All right, I think I've found a very nice workaround:

def line(a=0,b=0):
    x = np.arange(-10,10)
    y = a+x*b
    plt.xlim((-10,10))
    plt.ylim((-10,10))
    plt.plot(x, y)

sliders = widgets.interact(a=(-10,10,0.1), b=(-10,10,0.1))

def test(chose_defaults):
    if chose_defaults=="a":
        @sliders
        def h(a=5,b=5):
            return(line(a,b))
    if chose_defaults=="b":
        @sliders
        def h(a=0,b=1):
            return(line(a,b))
widgets.interact(test, chose_defaults=["a","b"])

The above code basically nests two widgets. Firstly a separate widget for chosing a scenario is shown; action for the scenarios are the plots that differ only in the default setup.

Upvotes: 0

Related Questions