How do you plot on a premade matplotlib plot with IPyWidgets?

Question:

I have a scenario where I would like to initialize the plot and plot a bunch of stuff on it before I run a widget on it. However, the jupyter widget refuses to plot on my already made plot. Instead, nothing shows up. A simplified example of this is below.

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

fig=plt.figure(1,(2,2))
axs=fig.gca()

def testAnimate(x):
    axs.text(0.5,0.5,x)

xs=widgets.IntSlider(min=0,max=3,value=1) #Create our intslider such that the range is [1,50] and default is 10

gui = widgets.interactive(testAnimate, x=xs) #Create our interactive graphic with the slider as the argument
display.display(gui)    #display it

I would expect the value of x to show up on axs, but it does not. I realize that in this case I could just do plt.text, however in my actual project that is not viable. So, how do I get the value of x to show up on my plot?

Thanks!

Asked By: waterBottle123

||

Answers:

Assuming that you are using Jupyter Notebook, you first have to initialize the interactive matplotlib. You can do that by running either one of the following magic commands:

  • %matplotlib notebook
  • %matplotlib widget. This one requires ipympl to be installed.

Then, execute:

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

fig, ax = plt.subplots()
text = ax.text(0.5, 0.5, "0")

def testAnimate(x):
    text.set_text(x)

xs=widgets.IntSlider(min=0,max=3,value=1) #Create our intslider such that the range is [1,50] and default is 10

gui = widgets.interactive(testAnimate, x=xs) #Create our interactive graphic with the slider as the argument
display.display(gui)    #display it
Answered By: Davide_sd

You were close. I had seen to put the plot creating in the function you call with the interactive wrapper. See here and here.

Translating that to your code by moving the two lines inside the function would have your notebook cell be:

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

def testAnimate(x):
    fig=plt.figure(1,(2,2))
    axs=fig.gca()
    axs.text(0.5,0.5,x)

xs=widgets.IntSlider(min=0,max=3,value=1) #Create our intslider such that the range is [1,50] and default is 10

gui = widgets.interactive(testAnimate, x=xs) #Create our interactive graphic with the slider as the argument
gui

Note that this works with %matplolib inline or actually without it at all as detailed in the comment at the top of the code there.
I don’t want the extra cruft and stuff that %matplotlib widget or %matplotlib notebook makes and makes the interactivity limited to the slider, like you seem to prefer as well.


And because the interactive ability of ipywidgets will make the widget automatically, you can simplify further to:

import matplotlib.pyplot as plt
import ipywidgets as widgets

def testAnimate(x):
    fig=plt.figure(1,(2,2))
    axs=fig.gca()
    axs.text(0.5,0.5,x)

gui = widgets.interactive(testAnimate, x=(0,3,1))
gui
Answered By: Wayne