0

I have an interactive plot, using matplotlib and ipywidgets, that is painfully slow, and so the display lags behind the interaction. One way to fix this is to tell my widget to be continuous_update=False, but I don't want to do this -- I like the user to see changes via continuous feedback.

I thought maybe I could check the queue of messages from the widget: if there are subsequent changes queued then the current state is out of date and I might as well suppress the plotting. The messages must surely be queued somewhere. Is this message queue accessible?

Here's a minimal example.

import matplotlib.pyplot as plt
import numpy
from IPython.display import display
import ipywidgets

# Don't want continuous_update=False
widg = ipywidgets.FloatSlider(value=.5,min=0,max=1,step=.01)
output = ipywidgets.Output()

def update_plot(msg):
    # ??? if there are further changes queued: return
    a = widg.value  # or msg['new']
    x = numpy.linspace(0,1,100)
    plt.plot(x, (x>=a) & (x<=a+.2))
    plt.ylim(-.02,1.02)
    output.clear_output(wait=True)
    with output:
        plt.show()

widg.observe(update_plot, 'value')

display(ipywidgets.VBox([widg, output]))
update_plot(None)
DamonJW
  • 3,342
  • 2
  • 24
  • 29
  • Maarten Breddels has written some useful code for a decorator that gives similar functionality: `debounced` (https://github.com/maartenbreddels/ipyvolume/blob/d13828dfd8b57739004d5daf7a1d93ad0839ed0f/ipyvolume/utils.py#L267) – ac24 Oct 21 '19 at 14:58
  • The Breddels code is for a different use case. I want the user to get feedback through continuous interaction (e.g. as you drag the slider back and forth you get to see how it impacts the output). The Breddels code is for debouncing (i.e. the update only happens once the user has finished, or at least paused, interacting). Debouncing can be achieved without peeking at the message queue, but I don't think my continuous-interaction case can. – DamonJW Nov 03 '19 at 04:19

0 Answers0