Matplotlib draw in console instead of cell output when call in widget event callback

Actually there’s several issues going on here.

I think the main one is that now with ipywidgets explicitly handling the output is necessary to control what goes to output vs. the Log console. You’ve noticed this using JupyterLab; however, since Jupyter Notebook 7+ is built on the same tech, it is necessary there now, too.

The second half of my posts here covers what you need to do to improve your code to current best practice to control output.
Additional posts addressing this practice with ipywidgets can be found here.

Additionally, I think though that matplotlib isn’t compatible with aysncio? I may completely misinterpreting a comment here:


There always seems to be multiple ways to do these things; however, I’m not seeing the need for asyncio here. You can use ipywidgets interactive and if you want the print prompts you include you can add them, sending them to the Output widget, see here. I think my code below addresses maybe much of what you were trying to do in your code example. I think you wanted to limit the user to repeating the plot 100 times? I didn’t implement that because I wasn’t following quite if that was the purpose or if it was necessary. (I think I can easily add it but not quite getting if it was needed and not wanting to slide 100 times to test it, I left it out for now.) Feel free to clarify and if my implementation lacks something else, please let me know?
It is largely based on here:

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

out = widgets.Output()

i = 0

def PlotAndNote(scale):
    global i
    x = np.arange(0, scale*np.pi,0.1)   # start,stop,step
    y = np.sin(x)
    plt.plot(x,y)
    with out:
        if scale == 0:
            print('did work %s'%i)
            i+=1
        else:
            print('did work %s'%i)
            print('plotting continued with value %s'%scale)
            i+=1

scale_slider=widgets.IntSlider(min=0,max=100,value=0, continuous_update = False) #Create our intslider such that the range is [0,100] and default is 0; and use `continuous_update = False` to restrict execution to mouse release events,see https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html#disabling-continuous-updates

gui = widgets.interactive(PlotAndNote, scale=scale_slider) #Create our interactive graphic with the slider as the argument
out_vbox = widgets.VBox([gui,out])
out_vbox

I left out %matplotlib inline as I think that is the default these days.

You can see the code work in temporary Jupyter sessions with ipywidgets installed already spawned via MyBinder.org by clicking here.

1 Like