4
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from ipywidgets import interact, FloatSlider, RadioButtons

amplitude_slider = FloatSlider(min=0.1, max=1.0, step=0.1, value=0.2)
color_buttons = RadioButtons(options=['blue', 'green', 'red'])
# decorate the plot function with an environment from the UIs:
@interact(amplitude=amplitude_slider, color=color_buttons)
def plot(amplitude, color):
    fig, ax = plt.subplots(figsize=(4, 3),
                       subplot_kw={'axisbg':'#EEEEEE',
                                   'axisbelow':True})

    ax.grid(color='w', linewidth=2, linestyle='solid')
    x = np.linspace(0, 10, 1000)
    ax.plot(x, amplitude * np.sin(x), color=color,
        lw=5, alpha=0.4)
    ax.set_xlim(0, 10)
    ax.set_ylim(-1.1, 1.1)

Using the widget multiple times got me multiple outputs:

enter image description here

What do I need to update in the code so the plot is cleared each time the widget is used?

jaycode
  • 2,926
  • 5
  • 35
  • 71

1 Answers1

4

I think there might be two problems:

  1. The first is that you create a new figure and axes each time the interactive elements are updated. So this new figure will be appended.
  2. Second, you are using the %matplotlib inline, which shows images of the plot. So once the plot is changed, a new image will be displayed instead of the current one changed.

An option might be to use the %matplotlib notebook backend.

One would then create the figure once and plot some initial values. We would also need to keep a reference to the artist, which should be updated by the widgets.

Once that is done, the interactive figure seems to conflict with the interactive widgets. In order to resolve this, I put all the interactive widgets (including their imports) in a new cell below the figure.

I'm not sure about the reasons for this happening, but the following seems to be a working solution.

Imports

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

Create the figure, plot an initial line

fig, ax = plt.subplots(figsize=(4, 3),
                       subplot_kw={'facecolor':'#EEEEEE',
                                   'axisbelow':True})
ax.grid(color='w', linewidth=2, linestyle='solid')
x = np.linspace(0, 10, 1000)
line, = ax.plot(x, 0.2 * np.sin(x), color="blue",
    lw=5, alpha=0.4)
ax.set_xlim(0, 10)
ax.set_ylim(-1.1, 1.1) 

Finally, in a new cell, do the interaction, only update the artists, not recreate them.

from ipywidgets import interact, FloatSlider, RadioButtons
amplitude_slider = FloatSlider(min=0.1, max=1.0, step=0.1, value=0.2)
color_buttons = RadioButtons(options=['blue', 'green', 'red'])
# decorate the plot function with an environment from the UIs:
@interact(amplitude=amplitude_slider, color=color_buttons)
def plot(amplitude, color):
    y = amplitude * np.sin(x)
    line.set_ydata(y)
    line.set_color(color)

Here is an image of how it would look like.

enter image description here

SherylHohman
  • 16,580
  • 17
  • 88
  • 94
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712