1

I'm having some problem implementing a "Debounce" decorator and combining it with matplotlib and ipywidget IntSlider.

Here below is the debounce code as suggested by the official ipywidgets documentation :

import asyncio

class Timer:
    def __init__(self, timeout, callback):
        self._timeout = timeout
        self._callback = callback
        self._task = asyncio.ensure_future(self._job())

    async def _job(self):
        await asyncio.sleep(self._timeout)
        self._callback()

    def cancel(self):
        self._task.cancel()

def debounce(wait):
    """ Decorator that will postpone a function's
        execution until after `wait` seconds
        have elapsed since the last time it was invoked. """
    def decorator(fn):
        timer = None
        def debounced(*args, **kwargs):
            nonlocal timer
            def call_it():
                fn(*args, **kwargs)
            if timer is not None:
                timer.cancel()
            timer = Timer(wait, call_it)
        return debounced
    return decorator

This is the code I'm using to implement @debounce while updating a plotted graph with widgets.IntSlider.

def plot():
    @debounce(0.1)
    def f(i):
        fig, ax = plt.subplots()
        ax.plot([i, i*i],[i,0 ], [0, i*2])
        ax.set_title(i)
    
    interact(f, i=IntSlider(min=0, max=10, value=4))

When I call the function plot() in a Jupyter Notebook's cell multiple graphs are plotted as I move the slider instead of updating the same fig, ax.

valerio_mc
  • 31
  • 3
  • 1
    Hi, the debounce is probably working as intended, but you need to display the matplotlib plot to an Output ipywidget, and then clear the output before plotting again. See here: https://stackoverflow.com/questions/50842160/how-to-display-matplotlib-plots-in-a-jupyter-tab-widget/51060721#51060721 – ac24 Jan 04 '21 at 09:24

0 Answers0