Benco
Benco

Reputation: 67

refresh matplotlib in Jupyter when updating with ipywidget

I want to draw a line in a Jupyter notebook, which can be moved using an ipywidget slider. I also want to have the mouse coordinates displayed, for which I'm using %matplotlib notebook. Here is what I have so far :

%matplotlib notebook
from ipywidgets import interact


fig, ax = plt.subplots()

@interact(n=(-200, 0))
def show(n):
    # fig.clear() #doesn't show anything
    y = -n+x
    ax.plot(x, y)
    
    plt.show()

When moving the line using the slider, the plot doesn't refresh, all previous positions of the line remain visible: enter image description here

I tried to refresh using fig.clear(), but then noting shows.

How can I solve this?

Upvotes: 0

Views: 2195

Answers (1)

Ianhi
Ianhi

Reputation: 3152

I have an extensive answer about this here: Matplotlib figure is not updating with ipywidgets slider

but the short of my recommendations are:

  1. use ipympl %matplotlib ipympl instead of notebook as this will play nicer with ipywidgets
  2. Use mpl-interactions to handle making plots controlled by sliders.
    • It will do the optimal thing of using set_data for you rather than clearing and replotting the lines.
    • It also interprets the shorthand for numbers in a way that (I think) makes more sense when making plots (e.g. using linspace instead of arange) see https://mpl-interactions.readthedocs.io/en/stable/comparison.html for more details.

So for your example I recommend doing:

install libraries

pip install ipympl mpl-interactions
%matplotlib ipympl
from ipywidgets import interact
import matplotlib.pyplot as plt
from mpl_interactions import ipyplot as iplt

x = np.linspace(0,100)
fig, ax = plt.subplots()

def y(x, n):
    return x - n
ctrls = iplt.plot(x, y, n=(-200,0))

it got a bit longer because I added the imports you left out of your question and also defined x.

Which gives you this:

gif of mouse interacting with slider and line updates

That said if you don't want to use those I think what you want is ax.cla() I think when you do fig.clear you are also removing the axes which is why nothing shows up.

%matplotlib notebook
from ipywidgets import interact


fig, ax = plt.subplots()

@interact(n=(-200, 0))
def show(n):
    y = -n+x
    ax.cla()
    ax.plot(x, y)

    plt.show()

Upvotes: 1

Related Questions