Skip to content

How to make interact ignore arguments? #2740

@TomNicholas

Description

@TomNicholas

Hi,

Firstly, widgets are amazing.

Now, I'm trying to create an interactive plotting function with a signature like interactively_plot(data, plotfunc, **kwargs). To do that I want to pass the function I want to interact with some arguments, which interact is to ignore, e.g.

def plotfunc(data, **kwargs):
    return data.plot()

def interactively_plot(data, plotfunc, **kwargs):
    wrapped = functools.partial(plotfunc, data=data)
    return interact(wrapped, **kwargs)

However, functools.partial doesn't behave as expected in this context: interact is still demanding that data be treated as a widget.

Here's a minimum example that demonstrates my problem

from ipywidgets import interact
from functools import partial, update_wrapper

# This is to avoid the error
# AttributeError: 'functools.partial' object has no attribute '__name__'
def wrapped_partial(func, *args, **kwargs):
    partial_func = partial(func, *args, **kwargs)
    update_wrapper(partial_func, func)
    return partial_func

def g(dat, x):
    print("dat={dat} from inside g")
    return dat

g_plus_dat = wrapped_partial(g, dat='a')

interact(g_plus_dat, x=10)

which raises

Traceback (most recent call last):
  File "/home/tegn500/Documents/Work/Code/experimentation/xwidget/mwe_partial.py", line 17, in <module>
    interact(g_plus_dat, x=10)
  File "/home/tegn500/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py", line 528, in __call__
    w = self.widget(f)
  File "/home/tegn500/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py", line 444, in widget
    return self.cls(f, self.opts, **self.kwargs)
  File "/home/tegn500/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py", line 188, in __init__
    new_kwargs = self.find_abbreviations(kwargs)
  File "/home/tegn500/anaconda3/lib/python3.7/site-packages/ipywidgets/widgets/interaction.py", line 288, in find_abbreviations
    raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name))
ValueError: cannot find widget or abbreviation for argument: 'dat'

I don't understand how what I've done is different from the use of functools.partial in this answer.

I could possibly get around this by using closures, but I really would rather not. I would also eventually like to do something similar but with methods.

Metadata

Metadata

Assignees

No one assigned

    Labels

    resolved-lockedClosed issues are locked after 30 days inactivity. Please open a new issue for related discussion.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions